谷粒商城-高级篇

本文介绍了谷粒商城的高级配置,包括配置nginx以通过gulimall.com访问项目,使用CompletableFuture进行异步编排,实现Oauth2.0 gitee登录,以及在购物车、消息队列和订单服务中的关键技术和解决方案。详细讲解了分布式事务的理论和实践,如本地事务、CAP理论和BASE理论,以及Sentinel在服务降级中的应用。

一、上架商品

上架商品:为了让前台可以看到商品,购买商品。
查询商品:前台查询商品主要是从es查询到的。
后台上架商品主要是传入一个spuId,通过这个spuId去查询sku相关信息,再将所有的商品上架

1、查出当前spuId对应的所有sku信息,品牌的名字
2、封装每个sku的信息
1、发送远程调用,库存系统查询是否有库存
2、热度评分。0
3、查询品牌和分类的名字信息
4、查出当前sku的所有可以被用来检索的规格属性

3、将数据发给es进行保存:gulimall-search
4、修改当前spu的状态为上架

二、配置nginx,通过访问gulimall.com访问项目

1、查看nginx.conf

在这里插入图片描述
可以看到在nginx/conf.d/下放配置文件,nginx会自动加载

2、创建gulimall.conf

在nginx/conf.d/创建gulimall.conf,可以通过配置proxy_pass将gulimall.com发送过来的请求转发
在这里插入图片描述

3、配置nginx.conf

将gulimall的请求转发给网关,设置一个unstream,配置一个server块(网关的端口)
在这里插入图片描述

4、配置gulimall.conf

将代理转发给nginx.conf配置好的http块
在这里插入图片描述

5、添加请求头

因为nginx在转发时会默认丢掉请求头,所以在gulimall.conf转发时添加请求头
在这里插入图片描述

6、网关配置

通过配置Host拦截带有gulimall.com请求头,然后转发给商品服务

#接口请求拦截
- id: product_route
          uri: lb://gulimall-product
          predicates:
            - Path=/api/product/**
          filters:
            - RewritePath=/api/(?<segment>/?.*),/$\{segment}


#请求头拦截
- id: gulimall_host_route
          uri: lb://gulimall-product
          predicates:
            - Host=gulimall.com,item.gulimall.com
            
            


请求头配置要在接口请求后面,不然通过Host访问的时候会直接转发到product服务去,有接口的话就去不掉/api
如果直接访问接口的话,就会直接转发到接口去

1.http://gulimall.com/api/product/attrattrgrouprelation/list
因接口拦截,转发到product服务并且去掉/api
2.http://gulimall.com因请求头拦截,转发到product服务

三、异步编排

使用CompletableFuture

CompletableFuture使用
https://blog.csdn.net/xiang_yu_pai/article/details/119065914

通过@ConfigurationProperties设置配置文件

@ConfigurationProperties(prefix = "gulimall.thread")
// @Component
@Data
public class ThreadPoolConfigProperties {
   
   

    private Integer coreSize;

    private Integer maxSize;

    private Integer keepAliveTime;


}

四、认证登录

Oauth2.0 gitee登录

社交登录认证流程
在这里插入图片描述

session不能跨域访问问题
在这里插入图片描述
session复制,将不同服务器里的session复制到别的服务器。
大型分布式集群情况下,不可取。
3-5台tomcat,量小,可试。
在这里插入图片描述
在这里插入图片描述
session都是保存在内存中,比redis快,如果用redis的话,还要去调用一次redis,增加网络调用;并且代码里所有跟session相关的代码都要改成从redis获取。
不过使用springsession可以很好的解决
在这里插入图片描述
在这里插入图片描述
springsession是将session存到了redis中(可以选择多个中间件存储,mangodb),通过一些配置就可以将存在内存中的session存到redis中,简单方便。
使用springsession,通过一些配置,实现子域放大,json序列化机制。

@Configuration
public class GulimallSessionConfig {
   
   

    @Bean
    public CookieSerializer cookieSerializer() {
   
   

        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();

        //放大作用域
        cookieSerializer.setDomainName("gulimall.com");
        cookieSerializer.setCookieName("GULISESSION");

        return cookieSerializer;
    }


    @Bean
    public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
   
   
        return new GenericJackson2JsonRedisSerializer();
    }

}

springsession原理

1、@EnableRedisHttpSession //开启springsession =》导入配置@Import({RedisHttpSessionConfiguration.class})=》
①、容器加入了一个组件 SessionRepository ===》 【RedisOperationsSessionRepository 】
(session的增删改查类,redis操作session)
2、SessionRepositoryFilter =》Filter 过滤器 session存储过滤器,每个请求过来都会经过Filter
①、创建的时候就会自动从容器获得SessionRepository (有参构造器)
②、doFilterInternal()
=》原始的request,response都被包装
③、以后获取session。request.getSession()
④、wrappedRequest,获取session都是操作SessionRepository

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
   
   
        request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);
        //包装原始请求
        SessionRepositoryFilter<S>.SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryFilter.SessionRepositoryRequestWrapper(request, response, this.servletContext);
        //包装原始响应
        SessionRepositoryFilter.SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryFilter.SessionRepositoryResponseWrapper(wrappedRequest, response);

        try 
        	//返回包装后的
            filterChain.doFilter(wrappedRequest, wrappedResponse);
        } finally {
   
   
            wrappedRequest.commitSession();
        }

    }

但是springsession可以通过放大作用域,使auth.gulimall.com和gulimall.com同时可以取到session,但是没法使gulimall.com和gulistudy.com同时取到session,也就是无法实现单点登录问题。

单点登录

解决方案:访问某一个受保护的资源时,就要去认证中心登录,并且在地址栏里将自己的地址作为回调地址传过去(参数),这样登录完之后将其保存在redis里,再返回client1,并带上token,这样带上token访问的话,就会得到数据。
如果client2访问的话,就还要登录,因此我们还要在访问ssoserver的时候,如果登录成功了在cookie里放sso-token,这样client2访问的时候,如果有sso-token的话,就直接返回地址带着token。

在这里插入图片描述

五、购物车

使用拦截器,实现当没有临时购物车user-key的时候,添加临时购物车的cookie

public class CartInterceptor implements HandlerInterceptor {
   
   

    public static ThreadLocal<UserInfoTo> threadLocal=new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
   
   
        UserInfoTo user = new UserInfoTo();
        HttpSession session=request.getSession();
        MemberResponseVo member = (MemberResponseVo) session.getAttribute(LOGIN_USER);
        if(member!=null){
   
   
            user.setUserId(member.getId());
        }
        Cookie[] cookies = request.getCookies();
        if(cookies!=null&&cookies.length>0){
   
   
            for (Cookie cookie : cookies) {
   
   
                String name = cookie.getName();
                if(name.equals(CartConstant.TEMP_USER_COOKIE_NAME)){
   
   
                    user.setUserKey(cookie.getValue());
                    user.setTempUser(true);
                }

            }
        }
        //没有临时用户
        if(StringUtils.isEmpty(user.getUserKey())){
   
   
            user.setUserKey(UUID.randomUUID().toString());
        }
        threadLocal.set(user);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
   
   
        UserInfoTo userInfoTo = threadLocal.get();
        if(!userInfoTo.isTempUser()<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值