springcloud项目整体搭建过程文档说明

简单的springcloud(采用的版本为:Finchley.RELEASE  springboot版本为:2.0.3.RELEASE):
    1.创建注册中心Eureka-server  
        1.1:需要的pom坐标:
            
                org.springframework.cloud
                spring-cloud-starter-netflix-eureka-server
            

        1.2:在启动类上加注解:
            @EnableEurekaServer :标识是一个注册中心
        1.3:添加配置文件  application.yml/application.properties
            server:
              port: 8761 #注册中心端口号

            eureka:
              instance:
                hostname: localhost
              client:
                #声明自己是一个服务
                registerWithEureka: false
                fetchRegistry: false
                serviceUrl: #注册中心地址
                  defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
        注:注册中心完成
    2.创建客户端(消费者,一个简单的客户端):
        2.1:需要的pom坐标:
            
                org.springframework.cloud
                spring-cloud-starter-netflix-eureka-client
            

        2.2:启动类添加注解:
            @EnableEurekaClient (注:这个注解可加可不加不影响) 声明这是一个客户端(消费着)
        2.3:修改配置文件:
            server:
              port: 8771 #客户端的端口号
            eureka:
              client:
                service-url:
                  defaultZone: http://localhost:8761/eureka/ #指定注册中心的地址
            spring:
              application:
                name: product-client #客户端的名称,必选项,注册中心需要用到,注册中心使用的就是此名称

    3.客户端间的调用:
        3.1:选择feign和ribbon feign中已经集成好了ribbon.  所以选择feign
            3.1.1:导入feign对应的pom坐标
                    
                        org.springframework.cloud
                        spring-cloud-starter-openfeign
                    

            3.1.2:如果是ribbon的话,对应的pom坐标
                     
                        org.springframework.cloud
                        spring-cloud-starter-netflix-ribbon
                    

                3.1.2.1:还需要在启动类中注入一个Bean,用于调用其他服务并开启负载均衡策略
                    @Bean
                    @LoadBalanced
                    public RestTemplate restTemplate(){
                        return new RestTemplate();
                    }
                3.1.2.2:调用方式:
                    a.注入RestTemplate类。
                    b.使用RestTemplate调用对应的方法。
                注:底层可查看@LoadBalanced。实际使用的是LoadBalancerClient这个类。内部通过这个去注册中心查找到对应的服务的所有节点,然后根据对应的负载均衡策略进行选择节点。然后返回给最外层,也就是选择好某个节点后进行调用,默认的负载均衡策略是轮询策略。可以配置负载均衡策略。配置完成后使用feign同样生效
                    #自定义负载均衡策略
                    product-client: #服务名称
                      ribbon:
                        NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule  随机策略可查看IRule类的子类。
                注:ribbon的默认超时时间为: 60秒
                    设置ribbon的超时和重试设置
                    ribbon:
                      ReadTimeout: 3000
                      ConnectTimeout: 3000    
                      MaxAutoRetries: 1 #同一台实例最大重试次数,不包括首次调用
                      MaxAutoRetriesNextServer: 1 #重试负载均衡其他的实例最大重试次数,不包括首次调用
                      OkToRetryOnAllOperations: false  #是否所有操作都重试  慎用
                    根据上面的参数计算重试的次数:MaxAutoRetries+MaxAutoRetriesNextServer+(MaxAutoRetries *MaxAutoRetriesNextServer) 即重试3次 则一共产生4次调用 
                    如果在重试期间,时间超过了hystrix的超时时间,便会立即执行熔断,fallback。所以要根据上面配置的参数计算hystrix的超时时间,使得在重试期间不能达到hystrix的超时时间,不然重试机制就会没有意义 
                    
                    hystrix超时时间的计算: (1 + MaxAutoRetries + MaxAutoRetriesNextServer) * ReadTimeout 即按照以上的配置 hystrix的超时时间应该配置为 (1+1+1)*3=9秒

                    Hystrix的超时计算规则应该是 Hystrix的超时时间=Ribbon的重试次数(包含首次)*(ribbon.ReadTimeout+ribbon.ConnectTimeout),如果以你的配置为例Hystrix的超时配置应该是=4*(3000+3000)=24000,即24秒。

                    当ribbon超时后且hystrix没有超时,便会采取重试机制。当OkToRetryOnAllOperations设置为false时,只会对get请求进行重试。如果设置为true,便会对所有的请求进行重试,如果是put或post等写操作,如果服务器接口没做幂等性,会产生不好的结果,所以OkToRetryOnAllOperations慎用。

                    如果不配置ribbon的重试次数,默认会重试一次 
                    注意: 
                    默认情况下,GET方式请求无论是连接异常还是读取异常,都会进行重试 
                    非GET方式请求,只有连接异常时,才会进行重试


            3.1.3:使用feign调用接口(基于接口实现feign);
                a.创建一个接口类,在接口类上加注解@FeignClient然后值有name 和 fallback   name:是需要调用的服务的名称
                                                                                         fallback:失败的回调(熔断处理,相当于家里的用电,当用电到达某一阈值,电路就会自动跳闸,从而保护整个电路。),失败的一个降级处理。写的是一个类。每一个方法对应一个方法,此方法参数类型和返回值必须和接口的一样。如果使用feign调用的接口失败了,则会进入这个方法,可以在内部进行一些操作并且返回一些虚拟数据,保证后续服务不会崩溃(解决雪崩效应)。
                b.使用feign调用接口的时候,如果有参数 基本类型传递使用@RequestParm   如果是对象的话,要使用@RequestBody传递。
                注:使用Feign调用接口分两层,ribbon的调用和hystrix的调用,所以ribbon的超时时间和Hystrix的超时时间的结合就是Feign的超时时间。一般情况下都是ribbon的超时时间(<)hystrix的超时时间(因为涉及到ribbon的重试机制因为ribbon的重试机制和Feign的重试机制有冲突,所以源码中默认关闭Feign的重试机制。
                hystrix的默认超时时间是一秒,配置了hystrix的超时时间必须还要配置ribbon的超时时间,否则会有问题。
                在使用 Ribbon 时,只需要配置 Hystrix 的超时时间就可以生效,不需要额外配置 Ribbon 的超时时间

                记录一个异常,就是第一次启动完成后,调用服务的时候总是在第一次出现超时的情况。这是因为懒加载的特性,在第一次用到的时候才去加载一些东西。而加载这些东西需要耗时,可能耗时的时候就已经出发了熔断/降级处理。
                解决办法有两种   1.设置超时时间:全局设置超时时间为60秒
                                                 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
                                                 # 设置ribbon超时时间
                                                 ribbon:
                                                   ReadTimeout: 20000
                                                   ConnectTimeout: 20000
                                 2. 配置立即加载。不过还需要配置所有的客户端服务
                                                 ribbon:
                                                    eager-load:
                                                        enabled: true
                                                        clients: distribution, material-product, outer-data  #客户端服务


        3.2:引入Hystrix(断路器,熔断)
            a.引入所需要的pom坐标文件
                
                    org.springframework.cloud
                    spring-cloud-starter-netflix-hystrix
                

            b.启动类开启断路器,加注解//@EnableHystrix
                                        @EnableCircuitBreaker   这两个都可以,上边的注解里包含了下边的注解。标识启用断路器功能。
            c.配置文件配置断路器。需要配置表示feign开启hystrix  和  hystrix的超时时间配置。hystrix的默认超时时间时1秒。
                feign:
                #开启断路器
                  hystrix:
                    enabled: true
                #修改调用超时时间
                  client:
                    config:
                      default:
                        connectTimeout: 3000
                        readTimeout: 2000

                #修改hystrix的调用超时时间配置
                hystrix:
                  command:
                    default:
                      execution:
                        isolation:
                          thread:
                            timeoutInMilliseconds: 4000
            d.使用:
                1. 在方法上加注解@HystrixCommand key有fallbackMethod  表示出现异常时要熔断的方法。
                    ps:访问该接口时报错了或者超时了,会进入fallbackMethod设置的对应的方法内部。进行一些记录操作返回一些给用户的提示等操作。
            注:1.feign/ribbon的超时时间一定要大于hystrix的超时时间,因为只要访问到接口,feign/ribbon 和 hystrix 的计时器就会同步启动,去计算。如果没有到达feign/ribbon的超时时间,但是到达了hystrix的超时时间,尽管没有报错,但是还是会进入的hystrix的熔断方法。  
                2.设置的fallbackMethod的方法的请求参数和返回结果要和@HystrixCommand标记的接口的一致,否则会出问题。
                

        3.3:引入hystrix仪表盘 hystrix-dashboard。一个健康检查。
            hystrix dashboard 仪表盘解释:健康检查监控hystrix的各项指标信息,检查接口调用的成功与失败记录等信息,如果失败率超过50%,会开启熔断,后续请求将不会请求接口。
            a:引入pom文件:
                
                    org.springframework.cloud
                    spring-cloud-starter-netflix-hystrix-dashboard
                

                
                
                    org.springframework.boot
                    spring-boot-starter-actuator
                

            b.启动类加注解:
                @EnableHystrixDashboard
            c.配置文件增加endpoint,开启所有访问权限,放行了所有端点,(这样貌似不安全,默认 Actuator 只暴露了2个端点,heath 和 info)
                management:
                  endpoints:
                    web:
                      exposure:
                        include: "*"
                注:这个是用来暴露 Actuator 的所有端点的,这一点很重要,不配置你的 Hystrix Dashboard 会出现 Unable to connect to Command Metric Stream 的问题
            d.访问入口
                http://localhost:8781/hystrix

                Hystrix Dashboard输入: http://localhost:8781/actuator/hystrix.stream 

        3.4:引入链路追踪:seluth,其主要作用是做一个日志的埋点,出现错误时可以根据日志的埋点id找到对应的信息/报错位置。Sleuth可以与日志框架Logback、SLF4J轻松地集成,
            a.引入pom文件
                
                    org.springframework.cloud
                    spring-cloud-starter-sleuth
                

            b.配置文件:
                spring:
                  #配置采样百分比,开发环境可以设置为1,表示全部,生产就用默认(比如请求100次我记录百分之多少/多少次。1代表全部,根据实际情况调节)
                  sleuth:
                    sampler:
                      probability: 1
            b. 集成可直接使用,但是需要加log否则控制台不会输出日志,本示例使用的是log4j
                private final Logger log = LoggerFactory.getLogger(getClass());
                log.info("查询商品");
            c.输出的格式
2020-03-26 16:32:08.117  INFO [product-client,1371c3a83b9b13a5,6ac4a8cc3fbbfa12,true] 1812 --- [nio-8772-exec-2] t.o.p.controller.ProductController: findProductById
2020-03-26 16:32:08.117  INFO [product-client,1371c3a83b9b13a5,6ac4a8cc3fbbfa12,true] 1812 --- [nio-8772-exec-2] t.o.product.service.ProductServiceImpl: 查询商品
                解释:[]中第一个标识服务的名称,第二个标识本次请求的id唯一标识(一个请求分配的ID号,用来标识一条请求链路。),第三个标识一个工作的基本单元,一个请求可以又多个步骤,而第三个标识每一个步骤。第四个表示  是否要将该信息输出到类似Zipkin这样的聚合器进行收集和展示。


        3.5:引入zipkin,上边所提到的聚合器,这里用于手机每次请求链路追踪所产生的记录,都在该组件内存在。
            a.引入pom文件:
                
                
                    org.springframework.cloud
                    spring-cloud-starter-zipkin
                

            b.配置文件:
                spring:
                  #zipkin服务所在地址
                  zipkin:
                    base-url: http://www.oyygke.top:9411/ #该地址表示zipkin所在地址
            c.使用:
                集成好sleuth和zipkin之后,进行发送请求,然后访问上边配置的zipkin的地址,就会看到请求记录。点击可查看详情--整个请求的链路是怎么走的。

        3.6:引入网关zuul
            a.引入pom文件
                
                    org.springframework.cloud
                    spring-cloud-starter-netflix-zuul
                

            b.添加注解,开启网关
                @EnableZuulProxy
               c.作用
                   使用网关进行过滤和请求转发的作用,经过网关转发到某服务。
               d.配置文件
                   zuul:
                  routes:
                    #相当于oyygke映射到order-client
                    order-client: /oyygke/order/**
                    product-client: /oyygke/product/**
                  #忽略product-client,不经过网关
                #  ignored-services: product-client
                  #只使用一种方式进行访问,过滤以client结尾的服务
                  ignored-patterns: /*-client/**
                  #处理http请求头为空的问题
                  sensitive-headers:
                ribbon: #添加请求超时设置,如果不配置,默认第一次访问会进入到熔断的超时处理机制。因为可能还没有加载到,第一次加载需要时间,所以需要添加超时时间设置。
                  ReadTimeout: 6000
                  ConnectTimeout: 6000
            e.使用过滤
                i.新建类继承ZuulFilter,实现其中的方法。相当于一个配置类,记得添加@component。还可以进行限流处理,
                    //令牌桶  每秒产生多少个令牌   这个需要进行压测确定可以有多少个令牌
                    //令牌需要配置到配置文件中更改   多少个网管就是  总数/网关数量
                    //guava谷歌的框架 限流
                    private static final RateLimiter RATE_LIMITER = RateLimiter.create(100);
                工具类:HttpStatus.TOO_MANY_REQUESTS.value()  //表示请求过多。
                示例:过滤token,表示   如果访问该接口没有token则过滤掉直接返回对应的错误提示信息。
                @Component
                public class LoginFilter extends ZuulFilter {
                    /**
                     * 过滤器的类型   前置还是后置
                     * @return
                     */
                    @Override
                    public String filterType() {
                        return PRE_TYPE; //表示请求接口前执行
                    }
                    /**
                     * 过滤器的一个级别  越小越先执行
                     * @return
                     */
                    @Override
                    public int filterOrder() {
                        return 4;
                    }
                    /**
                     * 是否进行过滤
                     * @return
                     */
                    @Override
                    public boolean shouldFilter() {
                        //全局的上下文对象
                        RequestContext context = RequestContext.getCurrentContext();
                        HttpServletRequest request = context.getRequest();
                        //如果请求路径包含order,则需要进行过滤验证
                        if(request.getRequestURI().contains("/order/")){
                            return true;
                        }
                        return false;
                    }
                    /**
                     * 业务逻辑
                     * @return
                     * @throws ZuulException
                     */
                    @Override
                    public Object run() throws ZuulException {
                        RequestContext context = RequestContext.getCurrentContext();
                        HttpServletRequest request = context.getRequest();

                        String token = request.getHeader("token");
                        if(StringUtils.isBlank(token)){
                            token = request.getParameter("token");
                        }
                        if(StringUtils.isBlank(token)){
                            context.setSendZuulResponse(false);
                            context.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
                        }
                        return null;
                    }
                }


        3.7:配置中心  config-server/config-client
            a.先搭建配置中心服务,config-server    配置中心可以使用   git、码云等 
            b.product-client-dev.yml  配置中心的文件名采用  服务名-后缀命名。dev/test等
            c.pom文件引入:
                
                    org.springframework.cloud
                    spring-cloud-config-server
                

            d.@EnableConfigServer  表示这是一个配置服务中心
            e.配置文件
                spring:
                  application:
                    name: config-server  #服务名称
                  cloud:
                    config:
                      server:
                        git:
                          uri: https://gitee.com/xc-rong/spring-cloud.git  #码云的项目地址
                          username: xxx  #码云账号
                          password: xxx #码云密码
                          timeout: 5
                          default-label: master #使用哪个分支的
            f.修改原有服务为配置中心的客户端  config-client
                i.引入pom文件
                    
                        org.springframework.cloud
                        spring-cloud-config-client
                    

                ii.修改原有的application.yml为bootstrap.yml /bootstrap.properties
                iii.修改配置文件
                    spring:
                      application:
                        name: order-client #服务名称
                      cloud:
                        config:
                          discovery:
                            enabled: true #开启通过服务访问config-server的功能
                            service-id: CONFIG-SERVER #配置中心的服务名
                          #后缀 一个区分  指定环境
                          profile: dev
                          #分支的区分,指定分支
                          label: master
                iiii. 将一些配置文件的内容放到填写的码云/git仓库上。项目启动的时候会从仓库拉去配置文件。
                注:到此配置完成,可以启动项目进行查看日志
            g.配置消息总线,用于动态拉取配置,(表示 在码云/git仓库更改配置文件之后,动态拉取不需要重启项目,但是线下可以这样,线上的话不建议这样,因为没办法观察是否拉取到了最新的配置文件)
                i:引入pom文件
                    
                        org.springframework.cloud
                        spring-cloud-starter-bus-amqp
                    

                ii.配置文件添加mq
                    spring:
                      application:
                        name: product-client
                      rabbitmq:
                        host: www.oyygke.top
                        port: 5672
                        username: guest
                        password: guest
                ii.添加注解,在需要动态更新配置的地方添加注解 @RefreshScope
                iii.至此代码中的内容添加完毕。动态更新的话需要手动的访问一个地址进行拉取最新配置
                    http://localhost:2009/refresh    #表示每个服务的ip+端口号+refresh 进行刷新,每次只刷新一个服务,多个服务需要调用多次,而且该接口只支持post请求,get请求不支持。

                   注:必须要有这个pom
                       
                    
                        org.springframework.boot
                        spring-boot-starter-actuator
                    

        4.完成以后可能会出现的小问题。
            注册中心每个服务的地址可能不是ip+端口号  可能是一串字母+端口号  这样放到线上是有问题的,需要在配置文件中在加下配置,使注册中心的地址是ip+端口号
            解决办法:
                eureka:
                  client:
                    service-url:
                      defaultZone: http://localhost:8761/eureka/
                  instance:
                    instance-id: ${spring.cloud.client.ip-address}:${server.port} #表示每个服务的ip示自定义id,ip+端口号格式
                    prefer-ip-address: true #将IP注册到Eureka Server上

你可能感兴趣的:(java,springCloud)