Spring Cloud Demo

这篇具有很好参考价值的文章主要介绍了Spring Cloud Demo。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Spring Cloud Demo

本文介绍Spring Cloud 常用的组件的demo代码。gitee代码:https://gitee.com/Aes_yt/spring-cloud-demo

包括Spring Cloud Eureka,Spring Cloud Feign,Spring Cloud Hystrix,Spring Cloud Ribbon,Spring Cloud Zuul,Spring Cloud Config,Spring Cloud Sleuth。

Spring Cloud Eureka

Server

  1. pom引入:

    <dependency>
    	<groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
    
  2. 代码:

    SpringBootApplication 启动类加入 @EnableEurekaServer注解。

  3. 配置:

    server:
      port: 8761
    
    eureka:
      instance:
        hostname: localhost
      client:
        register-with-eureka: false
        fetch-registry: false
        service-url:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      server:
        wait-time-in-ms-when-sync-empty: 0
        enable-self-preservation: false
    

Client

  1. pom引入:

    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
  2. 代码:

    SpringBootApplication 启动类加入 @EnableDiscoveryClient注解。

  3. 配置:

    server:
      port: 8081
    
    spring:
      application:
        name: demo-client1
    
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka/
    

TIPS. 非java语言也可使用Eureka提供的REST API接口接入Server。 wiki

常见问题

  1. 为什么服务上线了,Eureka Client 不能及时获取到。

    Eureka Server 的 REST API 有response cache,需要等缓存过期后才能更新数据。

  2. 为什么服务下线了,Eureka Server 接口返回的信息还会存在。

    应用实例异常挂掉,没有在挂掉之前告知Server 要下线。这个就需要依赖Eureka Server的EvictionTask 去剔除。

  3. 其他:

    springcloud对springboot的版本是有要求的,如果不一致,会启动不起来的。详细可以看官网的版本要求。

Spring Cloud Feign + Spring Cloud Hystrix

demo-hello

  1. 首先先创建一个 demo 的 module,接入Eureka配置(eureka-client )。设置端口8082,里面只有一个get方法,我们用postman调用 http://localhost:8082/hello/testGet?param=hello,能够正常返回。

    @RestController
    @RequestMapping("/hello")
    @Slf4j
    public class HelloController {
        @GetMapping("/testGet")
        public BaseResp<String> testGet(@RequestParam("param") String param) {
            log.info("[demo-hello] testGet:{}", param);
            return BaseResp.success(param);
        }
    }
    

    yml:

    server:
      port: 8082
    spring:
      application:
        name: demo-hello
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka/
    

feign-client

  1. 创建一个新module。引入Eureka-client依赖,feign依赖和hystrix依赖。

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!-- cloud 2020.0.x 之后无此依赖 -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    

    注意:hystrix 在 spring-cloud 2020.0.x 版本废弃,之后的版本推荐使用 Resilience4j 进行服务的熔断。

  2. yaml 配置

    server:
      port: 8083
    spring:
      application:
        name: feign-client
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka/
    
    feign:
    #  hystrix熔断开关
      hystrix:
        enabled: true
    #  feign-client的超时时间
      client:
        config:
          default:
            connect-timeout: 3000
            read-timeout: 3000
            logger-level: basic
    
    # 设置hystrix服务降级超时时间
    hystrix:
      command:
        default:
          execution:
            isolation:
              thread:
                timeoutInMilliseconds: 15000
    
  3. Application 注解

    @EnableFeignClients:@EnableFeignClients 是一个 Spring Cloud 注解,用于启用 Feign 客户端的功能。

    @EnableCircuitBreaker:@EnableCircuitBreaker 是 Spring Cloud 提供的一个注解,用于启用熔断器(Circuit Breaker)的功能。

    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    @EnableCircuitBreaker
    public class FeignClientApplication {
        public static void main(String[] args) {
            SpringApplication.run(FeignClientApplication.class, args);
        }
    }
    
  4. 建立Feign调用Service

    @FeignClient(name = "demo-hello", contextId = "feign-hello", path = "/hello", fallbackFactory = FeignHelloServiceHystrix.class)
    public interface FeignHelloService {
        @RequestMapping(value = "/testGet", method = RequestMethod.GET)
        BaseResp<String> testGet(@RequestParam("param") String param);
    }
    

    name = "demo-hello" 就是 demo 项目的 spring.application.name,contentxId 就相当于这个调用service的唯一id,path就是统一前缀。fallbackFactory 就是降级后的工厂。所以我们要实现这个工厂。

    我这边的逻辑,就是记录一下日志,然后返回统一的错误对象。

    @Slf4j
    @Component
    public class FeignHelloServiceHystrix implements FallbackFactory<FeignHelloService> {
        @Override
        public FeignHelloService create(Throwable cause) {
            log.error("feign调用helloController报错", cause);
            return new FeignHelloService() {
                public BaseResp<String> testGet(String param) {
                    return BaseResp.error(param);
                }
            };
        }
    }
    
  5. 测试一下,

        @GetMapping("/testGet")
        public BaseResp<String> testGet(@RequestParam("param") String param) {
    //        try {
    //            Thread.sleep(6000);
    //        } catch (InterruptedException e) {
    //            throw new RuntimeException(e);
    //        }
    //        if(!param.isEmpty()){
    //            throw new RuntimeException("error...");
    //        }
            log.info("[demo-hello] testGet:{}", param);
            return BaseResp.success(param);
        }
    

    testGet 6秒钟才响应或者直接抛出异常,都是会进入FeignHelloServiceHystrix中打印日志。

附加

  1. Feign 加日志打印

    1. xml配置Feign客户端

      # Feign 日志配置
      logging:
        level:
          com.yt.demo.service.feign: debug
      
    2. Feign 配置

      /**
       * Feign 配置
       */
      @Slf4j
      @Configuration
      public class FeignConfig {
      
          /**
           * NONE:不记录任何信息
           * BASIC:仅记录请求方法、URL以及响应状态码和执行时间.
           * HEADERS:除了记录BASIC级别的信息外,还会记录请求和响应的头信息
           * FULL:记录所有请求与响应的明细,包括头信息、请求体、元数据
           */
          @Bean
          Logger.Level feignLoggerLevel() {
              return Logger.Level.FULL;
          }
      }
      
    3. 效果如下:

      2023-06-23 11:38:43.026 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] ---> POST http://demo-hello/hello/testPost HTTP/1.1
      2023-06-23 11:38:43.026 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] Content-Length: 30
      2023-06-23 11:38:43.026 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] Content-Type: application/json
      2023-06-23 11:38:43.026 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] 
      2023-06-23 11:38:43.026 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] {"param":"Post method: hello"}
      2023-06-23 11:38:43.026 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] ---> END HTTP (30-byte body)
      2023-06-23 11:38:43.029 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] <--- HTTP/1.1 200 (2ms)
      2023-06-23 11:38:43.029 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] connection: keep-alive
      2023-06-23 11:38:43.029 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] content-type: application/json
      2023-06-23 11:38:43.029 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] date: Fri, 23 Jun 2023 03:38:43 GMT
      2023-06-23 11:38:43.029 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] keep-alive: timeout=60
      2023-06-23 11:38:43.029 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] transfer-encoding: chunked
      2023-06-23 11:38:43.029 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] 
      2023-06-23 11:38:43.029 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] {"code":200,"data":"Post method: hello","msg":"success"}
      2023-06-23 11:38:43.029 DEBUG 496 --- [ix-demo-hello-4] c.y.d.service.feign.FeignHelloService    : [FeignHelloService#testPost] <--- END HTTP (56-byte body)
      
  2. 文件上传

    1. feign Client 里面新增文件上传方法

          @RequestMapping(value = "/testFile", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE,
                  consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
          BaseResp<String> testFile(@RequestPart("file") MultipartFile file);
      

      注意配置@RequestPart 注解,参数加上:produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE

常见问题

  1. demo项目的方法返回报错,或者超时,都并没有进入熔断工厂。

    检查一下feign-client的hystrix是否启用: feign.hystrix.enabled: true

  2. 配置了feign-client的超时时间为3s,demo返回时间6s,但是1s就马上进入熔断工厂报超时,并没有等待3s。

    feign-client的超时时间和hystrix的超时时间都要配置。

  3. 配置了超时时间,但是还是不生效。

    根据你的cloud版本搜索一下,对应的配置怎么配。有可能不同版本的配置方法不一样,单词改变了之类的都是有可能的。

  4. feign调用报错:Load balancer does not have available server for client : xxx

    feign客户端的yaml配置加上 fetch-registry: true

    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka/
        fetch-registry: true
    

Spring Cloud Ribbon

demo-hello

  1. demo-hello 复用上面Feign的controller新增一个测试方法,打印出当前服务器端口

        @GetMapping("/testRibbon")
        public BaseResp<String> testRibbon(@RequestParam("param") String param, HttpServletRequest httpServletRequest) {
            log.info("接收到请求,参数:{}, serverPort:{}", param, httpServletRequest.getServerPort());
            return BaseResp.success("Response from server port: " + httpServletRequest.getServerPort());
        }
    
  2. 启动项目,之后修改application.xml的端口号port,重新启动一个实例。

  3. 启动成功之后,在Eureka界面可以看到两个启动的实例。

    Application AMIs Availability Zones Status
    DEMO-HELLO n/a (2) (2) UP (2) - 192.168.0.101:demo-hello:8082 , 192.168.0.101:demo-hello:8084

ribbon-client

  1. 新建一个项目。[可以从Eureka-client复制,然后修改spring.application.name和pom文件的artifactId]。

  2. 引入ribbon依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
    
  3. 新建ribbon配置类,重点是用@LoadBalance注解来声明restTemplate具有负载均衡能力。而且这样在使用restTeamplate的时候就能通过eureka上面的服务名来调用服务了,

    @Slf4j
    @Configuration
    public class RibbonConfig {
    
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }
    
  4. 新建一个测试类,直接调用十次请求

    @RestController
    @RequestMapping("/client")
    @Slf4j
    public class HelloController {
        @Autowired
        private RestTemplate restTemplate;
    
        @GetMapping("/testRibbon")
        public BaseResp<String> testRibbon(@RequestParam("param") String param) {
            String url = "http://demo-hello/hello/testRibbon?param=" + param;
    		
            for (int i = 0; i < 10; i++) {
                BaseResp<?> resp = restTemplate.getForObject(url, BaseResp.class);
                log.info("i-{}: {}", i, resp);
            }
            return BaseResp.success(null);
        }
    }
    
  5. 返回结果:

    2023-06-23 15:42:40.802  INFO 7916 --- [nio-8085-exec-2] com.yt.demo.controller.HelloController   : i-0: BaseResp(code=200, data=Response from server port: 8084, msg=success)
    2023-06-23 15:42:40.805  INFO 7916 --- [nio-8085-exec-2] com.yt.demo.controller.HelloController   : i-1: BaseResp(code=200, data=Response from server port: 8082, msg=success)
    2023-06-23 15:42:40.807  INFO 7916 --- [nio-8085-exec-2] com.yt.demo.controller.HelloController   : i-2: BaseResp(code=200, data=Response from server port: 8084, msg=success)
    2023-06-23 15:42:40.810  INFO 7916 --- [nio-8085-exec-2] com.yt.demo.controller.HelloController   : i-3: BaseResp(code=200, data=Response from server port: 8082, msg=success)
    2023-06-23 15:42:40.812  INFO 7916 --- [nio-8085-exec-2] com.yt.demo.controller.HelloController   : i-4: BaseResp(code=200, data=Response from server port: 8084, msg=success)
    2023-06-23 15:42:40.814  INFO 7916 --- [nio-8085-exec-2] com.yt.demo.controller.HelloController   : i-5: BaseResp(code=200, data=Response from server port: 8082, msg=success)
    2023-06-23 15:42:40.818  INFO 7916 --- [nio-8085-exec-2] com.yt.demo.controller.HelloController   : i-6: BaseResp(code=200, data=Response from server port: 8084, msg=success)
    2023-06-23 15:42:40.820  INFO 7916 --- [nio-8085-exec-2] com.yt.demo.controller.HelloController   : i-7: BaseResp(code=200, data=Response from server port: 8082, msg=success)
    2023-06-23 15:42:40.824  INFO 7916 --- [nio-8085-exec-2] com.yt.demo.controller.HelloController   : i-8: BaseResp(code=200, data=Response from server port: 8084, msg=success)
    2023-06-23 15:42:40.826  INFO 7916 --- [nio-8085-exec-2] com.yt.demo.controller.HelloController   : i-9: BaseResp(code=200, data=Response from server port: 8082, msg=success)
    

    ribbon的默认负载均衡策略是ZoneAvoidanceRule,可以看出请求分别调到了8084和8082两个服务实例上。

  6. 负载均衡策略配置

    1. Ribbon内置的负载均衡规则:

      规则名称 特点
      AvailabilityFilteringRule 过滤掉一直连接失败的被标记为circuit tripped的后端Server,并 过滤掉那些高并发的后端Server或者使用一个AvailabilityPredicate 来包含过滤server的逻辑,其实就是检查status里记录的各个server 的运行状态
      BestAvailableRule 选择一个最小的并发请求的server,逐个考察server, 如果Server被tripped了,则跳过
      RandomRule 随机选择一个Server
      WeightedResponseTimeRule 根据响应时间加权,响应时间越长,权重越小,被选中的可能性越低
      RetryRule 对选定的负载均衡策略加上重试机制,在一个配置时间段内当 选择Server不成功,则一直尝试使用subRule的方式选择一个 可用的Server
      RoundRobinRule 轮询选择,轮询index,选择index对应位置的Server
      ZoneAvoidanceRule 复合判断Server所在区域的性能和Server的可用性 选择Server,在没有区域的环境下,类似于轮询(RandomRule)
    2. 修改策略为随机:

      RibbonConfig.java 新增配置[全局]

      /**
       * 配置轮询策略为RandomRule
       * 其他的策略配置也一样,策略类路径都是 com.netflix.loadbalancer.xxx
       */
      @Bean
      public IRule ribbonRule(){
          return new RandomRule();
      }
      

      或:按服务粒度进行配置:(demo-hello 是目标服务的服务名)

      demo-hello:
        ribbon:
          NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
      

      我直接配置全局的 ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule不生效,不知道是不是不支持全局配置。

      效果:

      2023-06-23 15:59:31.095  INFO 11492 --- [nio-8085-exec-3] com.yt.demo.controller.HelloController   : i-0: BaseResp(code=200, data=Response from server port: 8082, msg=success)
      2023-06-23 15:59:31.097  INFO 11492 --- [nio-8085-exec-3] com.yt.demo.controller.HelloController   : i-1: BaseResp(code=200, data=Response from server port: 8084, msg=success)
      2023-06-23 15:59:31.100  INFO 11492 --- [nio-8085-exec-3] com.yt.demo.controller.HelloController   : i-2: BaseResp(code=200, data=Response from server port: 8084, msg=success)
      2023-06-23 15:59:31.104  INFO 11492 --- [nio-8085-exec-3] com.yt.demo.controller.HelloController   : i-3: BaseResp(code=200, data=Response from server port: 8082, msg=success)
      2023-06-23 15:59:31.108  INFO 11492 --- [nio-8085-exec-3] com.yt.demo.controller.HelloController   : i-4: BaseResp(code=200, data=Response from server port: 8084, msg=success)
      2023-06-23 15:59:31.112  INFO 11492 --- [nio-8085-exec-3] com.yt.demo.controller.HelloController   : i-5: BaseResp(code=200, data=Response from server port: 8084, msg=success)
      2023-06-23 15:59:31.117  INFO 11492 --- [nio-8085-exec-3] com.yt.demo.controller.HelloController   : i-6: BaseResp(code=200, data=Response from server port: 8084, msg=success)
      2023-06-23 15:59:31.124  INFO 11492 --- [nio-8085-exec-3] com.yt.demo.controller.HelloController   : i-7: BaseResp(code=200, data=Response from server port: 8082, msg=success)
      2023-06-23 15:59:31.132  INFO 11492 --- [nio-8085-exec-3] com.yt.demo.controller.HelloController   : i-8: BaseResp(code=200, data=Response from server port: 8084, msg=success)
      2023-06-23 15:59:31.137  INFO 11492 --- [nio-8085-exec-3] com.yt.demo.controller.HelloController   : i-9: BaseResp(code=200, data=Response from server port: 8082, msg=success)
      

Spring Cloud Zuul

zuul-server

  1. 新建项目 [可以从Eureka-client复制,然后修改spring.application.name和pom文件的artifactId]。

  2. 引入Eureka-client依赖和zuul依赖

    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
    
  3. 启动类加注解: @EnableZuulProxy

  4. application.yml 配置文件,加上zuul配置

    server:
      port: 8888
    
    spring:
      application:
        name: zuul-server
    
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka/
    
    # 将 /demo-hello/ 开头的请求,转到demo-hello组件中
    zuul:
      routes:
        demo-hello:
          path: /demo-hello/**
          serviceId: demo-hello
    #      也可以直接设置url
    #      url: http://localhost:8082/
    
  5. 启动 demo-hello 组件,调用请求: http://localhost:8888/demo-hello/hello/testGet?param=this_is_param,demo-hello[8082] 得到结果。等同于直接调用demo-hello的请求:http://localhost:8082/hello/testGet?param=this_is_param

  6. 路由前缀

    zuul:
      routes:
        demo-hello:
          path: /demo-hello/**
          serviceId: demo-hello
      prefix: /pre
    

    我们可以配置zuul.prefix来设置统一前缀。像我这样配置的话,就是得访问:http://localhost:8888/pre/demo-hello/hello/testGet?param=this_is_param,才能跟上面的请求等效。

  7. 屏蔽服务、路径

    zuul:
      ignored-services: demo-hello
      ignored-patterns: /**/hello/**
    

请求过滤

  1. 我们可以根据过滤规则,对访问的请求进行校验。不符合规则的可以直接过滤返回。比如我们可以校验请求的参数是否有token参数。

  2. 新建过滤器:

    @Slf4j
    public class AccessFilter extends ZuulFilter {
        /**
         * 过滤器类型
         * pre: 在请求被路由前调用
         * routing: 在路由请求时调用
         * error: 在处理请求时发生错误时调用
         * post: 在routing和error过滤器之后调用
         */
        @Override
        public String filterType() {
            return "pre";
        }
    
        /**
         * 过滤器的执行顺序,数值越小越优先
         */
        @Override
        public int filterOrder() {
            return 0;
        }
    
        /**
         * 是否启用过滤
         */
        @Override
        public boolean shouldFilter() {
            return true;
        }
    
        /**
         * 具体过滤逻辑
         */
        @Override
        public Object run() throws ZuulException {
            RequestContext currentContext = RequestContext.getCurrentContext();
            HttpServletRequest request = currentContext.getRequest();
    
            log.info("zuul接收到请求,参数:{}", request.getParameterMap());
            log.info("zuul接收到请求,参数:{}", request.getParameter("token"));
    
            if (request.getParameterMap().get("token") == null) {
                log.info("请求参数未包含token字段,返回");
                currentContext.setResponseStatusCode(401);
                currentContext.setSendZuulResponse(false);
                return null;
            }
    
            log.info("正常请求,放行");
            return null;
        }
    }
    
  3. 创建bean

    @Slf4j
    @Configuration
    public class ZuulConfig {
        @Bean
        public AccessFilter accessFilter() {
            return new AccessFilter();
        }
    }
    
  4. 测试

    请求 http://localhost:8888/pre/demo-hello/hello/testGet?param=this_is_param&token=gyt%26kal13 可以正常调到demo-hello组件里的方法。

    请求http://localhost:8888/pre/demo-hello/hello/testGet?param=this_is_param返回401错误码

Spring Cloud Config

config-server

  1. 引入依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
    
  2. 启动类添加注解 @EnableConfigServer

  3. bootstrap.yaml配置

    server:
      port: 8086
    
    spring:
      application:
        name: config-server
    
      cloud:
        config:
          server:
            git:
              uri: https://gitee.com/Aes_yt/spring-cloud-demo.git
    #          git 仓库的相对搜索路径
              search-paths: config-repo
              username: xxxx
              password: xxxx
              default-label: master
    
  4. git 配置

    第三点使用的是git配置,所以我们需要有一个git仓库。我已经事先建好了,配置文件放在git仓库的config-repo路径下。

    在config-repo上传配置文件,例如上传不同环境的三个配置文件:

    config-client.yaml

    config:
      name: myConfig
    

    config-client-dev.yaml

    config:
      name: myConfig-dev
    

    config-client-test.yaml

    config:
      name: myConfig-test
    

    config-client 是我待会要创建的client项目的application.name,文件名的明明规则就是 {name}-{profile}.yaml 或 .properties。文件内容的配置文件就跟普通的yaml项目一样,配置所需要的一些配置,我这边是随便配置了一个变量名 ${config.name},后面再输出打印测试。

  5. 先测试。启动config-server,访问地址 : http://localhost:8086/config-client/dev,可以看到输出配置信息。

    {
    	"name": "config-client",
    	"profiles": ["dev"],
    	"label": null,
    	"version": "2ec77d4a4f8050fa5a032cf5ff27ff8583d3f663",
    	"state": null,
    	"propertySources": [{
    		"name": "https://gitee.com/Aes_yt/spring-cloud-demo.git/config-repo/config-client-dev.yaml",
    		"source": {
    			"config.name": "myConfig-dev"
    		}
    	}, {
    		"name": "https://gitee.com/Aes_yt/spring-cloud-demo.git/config-repo/config-client.yaml",
    		"source": {
    			"config.name": "myConfig"
    		}
    	}]
    }
    

    也可以直接访问 http://localhost:8086/config-client-dev.yaml 查看yaml配置内容

    config:
      name: myConfig-dev
    

config-client

  1. 引入maven依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>
    
  2. bootstrap.yaml配置(我这里用application.yaml 配置启动会报错)

    spring:
      application:
        name: config-client
      cloud:
        config:
          label: master
    #     config-server的地址
          uri: http://localhost:8086/
    #      环境
          profile: dev
    
    server:
      port: 8087
    
  3. 新建一个测试类,检测配置值

    @RestController
    @RequestMapping("/config")
    public class ConfigTestController {
        @Value("${config.name}")
        private String configName;
    
        @GetMapping("/test")
        public String test() {
            return configName;
        }
    }
    
  4. 启动项目,能看到控制台输出,会打印出当前使用的配置信息

    2023-07-22 10:42:16.447  INFO 13592 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Fetching config from server at : http://localhost:8086/
    2023-07-22 10:42:17.480  INFO 13592 --- [           main] c.c.c.ConfigServicePropertySourceLocator : Located environment: name=config-client, profiles=[dev], label=master, version=2ec77d4a4f8050fa5a032cf5ff27ff8583d3f663, state=null
    

    能看出当前环境是 name=config-client, profiles=[dev], label=master ,所以会去maven仓库找到master分支的 config-client-dev 的配置文件。如果找不到的话,在 @Value("${config.name}") 时则会报错。

  5. 测试,访问 http://localhost:8087/config/test

    myConfig-dev

结合Eureka

  1. 结合Eureka使用,首先server和client都要引入Eureka-client依赖,pom中引入spring-cloud-starter-netflix-eureka-client 。其次,启动类都要加上 @EnableDiscoveryClient 注解。最后yaml中都需要加上配置 eureka.client.service-url.defaultZone=http://localhost:8761/eureka/ ,这三个都可参考上文的Eureka-client配置。

  2. config-client加上discovery配置:

    spring:
      application:
        name: config-client
      cloud:
        config:
          label: master
          #     config-server的地址
    #      uri: http://localhost:8086/
          #      环境
          profile: dev
    
    #      使用eureka发现服务
          discovery:
            enabled: true
            service-id: config-server
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka/
    
    server:
      port: 8087
    

Spring Cloud Sleuth

Sleuth 能够对服务间调用的链路进行监控追踪,之前学习 Feign 的时候,我们用 Feign-client 组件,调用了 demo-hello 组件的testGet方法,所以我们可以在之前的Feign-client 和 demo-hello 组件的基础上进行修改验证,添加Sleuth依赖,来观察服务间的调用情况。

  1. 添加Sleuth依赖

  2. 运行,调用,观察打印的日志

    feign-client:

    2023-07-23 10:10:11.296 DEBUG [feign-client,f307a05d85938646,f8b404471ba7448a,true] 15956 --- [ix-demo-hello-5] 
    2023-07-23 10:10:11.296 DEBUG [feign-client,f307a05d85938646,f8b404471ba7448a,true] 15956 --- [ix-demo-hello-5] 
    2023-07-23 10:10:11.416 DEBUG [feign-client,f307a05d85938646,f8b404471ba7448a,true] 15956 --- [ix-demo-hello-5] 
    ...
    

    demo-hello:

    2023-07-23 10:10:11.398  INFO [demo-hello,f307a05d85938646,51bf5d6b238302e9,true] 11736 --- [nio-8082-exec-1] com.yt.demo.controller.HelloController   : [demo-hello] testGet:Get method: hello
    

    可以从控制台的日志发现,日志多了[feign-client,f307a05d85938646,f8b404471ba7448a,true]部分,第一个参数代表application.name,第二个参数 f307a05d85938646 则是一个请求链路的 Trace ID,第三个参数f8b404471ba7448a表示SpanId,是一个基本的工作单元,第四个参数表示是否要将该信息输出到Zipkin等服务中来收集和展示。

    从feign-client 到 demo-hello 中, Trace ID 都是f307a05d85938646,所以可以将一个请求在不同服务中的日志串联起来。文章来源地址https://www.toymoban.com/news/detail-613271.html

到了这里,关于Spring Cloud Demo的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring Cloud Alibaba-01-微服务介绍

    Lison dreamlison@163.com , v1.0.0 , 2023.05.07 架构的演变 随着互联网的发展,网站应用的规模也不断的扩大,进而导致系统架构也在不断的进行变化,从互联网早起到现在,系统架构大体经历了下面几个过程: 单体应用架构: 把所有功能都集中在一个应用中,统一部署,开发成本、

    2024年02月22日
    浏览(73)
  • Spring Cloud Alibaba 介绍与版本映射关系

    目录 前言 一、Spring Cloud Alibaba 是什么? 二、Spring Cloud Alibaba 版本依赖         Spring Cloud 本身并不是一个拿来即可用的框架,它是一套微服务规范,这套规范共有两代实现。 (子项目): ● 第一代实现: Spring Cloud Netflix, ● 第二代实现: Spring Cloud Alibaba。 2018 年 12 月1

    2024年02月03日
    浏览(34)
  • Nacos 单机集群搭建及常用生产环境配置 | Spring Cloud 3

    Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 Nacos 致力于帮助您发现、配置和管理微服务。 Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据

    2024年02月03日
    浏览(34)
  • 【Spring Cloud】关于Nacos配置管理的详解介绍

    🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《Spring Cloud》。🎯🎯 👉点击这里,就可以查看我的主页啦!👇👇 Java方文山的个人主页 🎁如果感觉还不错的话请给我点赞吧!🎁🎁 💖期待你的加入,一起

    2024年02月01日
    浏览(45)
  • Spring Cloud-Config介绍及Git入门

    二、Spring cloud config 分布式配置中心能干吗? ================================= (1)集中式管理配置文件 (2)不同环境,不同配置,动态化的配置更新,分环境部署,比如 /dev /test /prod /beta /release (3)运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务

    2024年04月12日
    浏览(34)
  • 【Spring Cloud】微服务架构演变及微服务架构介绍

    欢迎来到阿Q社区 https://bbs.csdn.net/topics/617897123 随着互联网的发展,网站应用的规模也在不断的扩大,进而导致系统架构也在不断的进行变化。从互联网早期到现在,系统架构大体经历了下面几个过程:单体应用架构—垂直应用架构—分布式架构—SOA架构—微服务架构,当然还

    2024年02月02日
    浏览(47)
  • Spring Cloud Gateway 服务网关的部署与使用详细介绍

    1、什么是服务网关:         传统的单体架构中只需要开放一个服务给客户端调用,但是微服务架构中是将一个系统拆分成多个微服务,如果没有网关,客户端只能在本地记录每个微服务的调用地址,当需要调用的微服务数量很多时,它需要了解每个服务的接口,这个工

    2024年02月02日
    浏览(44)
  • 微服务之Spring Cloud Alibaba Sentinel介绍与下载(详细方法)

    随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应过载保护、热点流量防护等多个维度保护服务的稳定性。 2012 年,Sentinel 诞生,主要功能为入口流量控制。 2013-2017 年,Sentinel 在阿里巴巴

    2024年02月11日
    浏览(53)
  • Spring Cloud Alibaba全家桶(六)——微服务组件Sentinel介绍与使用

    本文小新为大家带来 微服务组件Sentinel介绍与使用 相关知识,具体内容包括 分布式系统存在的问题 , 分布式系统问题的解决方案 , Sentinel介绍 , Sentinel快速开始 (包括: API实现Sentinel资源保护 , @SentinelResource注解实现资源保护 ), Sentinel控制台 , Spring Cloud Alibaba整合

    2024年01月17日
    浏览(53)
  • Spring Cloud Alibaba 整合Seata 之概念介绍及Seata-server搭建

    目录 前言 基础介绍 官方文档 模式分类 角色介绍 Seata Server 部署 -  docker-compose  数据库 服务器  nacos配置 docker-compose.yaml 启动 后记 Seata 是 阿里巴巴 开源的 分布式事务中间件,以 高效 并且对业务 0 侵入 的方式,解决 微服务 场景下面临的分布式事务问题。 主要指讲述

    2024年02月07日
    浏览(80)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包