Tenth power learning - spring cloud (9)

1. Architecture evolution

  1. Centralized, all functions are concentrated in the same project. When the amount of access and data continues to increase, the system will be overwhelmed.
  2. SOA-style, service-oriented architecture, he uses vertical and horizontal means to divide a complete system into multiple projects for design by "demolition". Vertically, it is divided according to business functions, and each part is parallel; horizontally, it is divided according to the call level of the system, and each part is called layer by layer from top to bottom, such as the design pattern of mvc. When there are many services in this architecture, the calls between services are intricate. At this time, service registration and subscription mechanisms, as well as scheduling and monitoring are required. At this time, distributed projects based on dubbo and zookeeper appeared.
  3. Microservice phase.
    • The business handled by each service is small enough, and the architect must first think of how to split a project into small enough when the initial design is made.
    • The number of people in the development team should be small enough, usually three to four people.
    • There are many kinds of technologies used in development.
    • Each service uses a separate database.
    • The calls between services adopt the http protocol, because microservices must provide rest-style APIs externally.
    • Microservices must implement centralized registration, which is a mechanism for unified management of microservices.
    • Unified configuration management.
    • The bus mechanism ensures mutual calls between services.

Two, spring cloud framework

  • It is after the emergence of spring boot. In order to provide sufficient management of the microservice system, spring uses Netflix's existing products and combines it with spring boot for unified use. So the premise of using spring cloud must be to use spring boot.

3. Build a project for inter-service access

  1. About the version of spring cloud.

    • Different spring boot versions correspond to different spring cloud versions.
    • The latest version of spring cloud 2020.0.x aka Ilford corresponds to spring boot 2.4.xx. The problem is that the latest version has stopped updating and maintaining eureka and all other components. Except for eureka, other components have been eliminated.
    • The original spring cloud components now have their own alternatives.
    • In order to be able to use all components, spring boot needs to reduce the version, such as 2.1.7.
  2. A simple example:

    • package com.zhong.consumer;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.context.annotation.Bean;
      import org.springframework.web.client.RestTemplate;
      
      /**
       * @author 华韵流风
       * @ClassName ComsumerApplication
       * @Date 2021/10/15 15:51
       * @packageName com.zhong.comsumer
       * @Description TODO
       */
      @SpringBootApplication
      public class ConsumerApplication {
              
              
          public static void main(String[] args) {
              
              
              SpringApplication.run(ConsumerApplication.class);
          }
      
          @Bean
          public RestTemplate restTemplate() {
              
              
              return new RestTemplate();
          }
      }
      
    • package com.zhong.provider.controller;
      
      import com.zhong.provider.pojo.User;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.bind.annotation.RestController;
      
      /**
       * @author 华韵流风
       * @ClassName ProviderController
       * @Date 2021/10/15 15:54
       * @packageName com.zhong.provider.controller
       * @Description TODO
       */
      @RestController
      @RequestMapping("/provider")
      public class ProviderController {
              
              
      
          @GetMapping("/user")
          public User user(@RequestParam String id) {
              
              
              User user = new User();
              user.setId(id);
              user.setName("张三");
              return user;
          }
      }
      
    • package com.zhong.consumer.controller;
      
      import com.zhong.consumer.pojo.User;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.*;
      import org.springframework.web.client.RestTemplate;
      
      /**
       * @author 华韵流风
       * @ClassName ProviderController
       * @Date 2021/10/15 15:54
       * @packageName com.zhong.provider.controller
       * @Description TODO
       */
      @RestController
      @RequestMapping("/consumer")
      public class ConsumerController {
              
              
      
          @Autowired
          private RestTemplate restTemplate;
      
          @GetMapping("/user/{id}")
          public User user(@PathVariable String id) {
              
              
              //访问provider服务,得到user数据
              return restTemplate.getForObject("http://localhost:80/provider/user?id=" + id, User.class);
          }
      }
      
  3. Create a registry based on eureka

    • <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <parent>
              <artifactId>springcloudtest</artifactId>
              <groupId>com.zhong</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>server_eureka</artifactId>
      
          <dependencies>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
              </dependency>
          </dependencies>
      
      </project>
      
    • package com.zhong.eureka;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
      
      /**
       * @author 华韵流风
       * @ClassName EurekaApplication
       * @Date 2021/10/15 16:54
       * @packageName com.zhong.eureka
       * @Description TODO
       */
      @SpringBootApplication
      @EnableEurekaServer
      public class EurekaApplication {
              
              
          public static void main(String[] args) {
              
              
              SpringApplication.run(EurekaApplication.class);
          }
      }
      
    • server:
        port: 10086
      spring:
        application:
          name: server-eureka
      eureka:
        client:
          service-url:
            defaultZone: http://localhost:10086/eureka
      
  4. Let the service provider and consumer register with the registration center:

    • server:
        port: 80
      spring:
        application:
          name: server-provider
      eureka:
        client:
          service-url:
            defaultZone: http://localhost:10086/eureka
      
    • package com.zhong.consumer;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
      import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
      import org.springframework.context.annotation.Bean;
      import org.springframework.web.client.RestTemplate;
      
      /**
       * @author 华韵流风
       * @ClassName ComsumerApplication
       * @Date 2021/10/15 15:51
       * @packageName com.zhong.comsumer
       * @Description TODO
       */
      @SpringBootApplication
      //@EnableEurekaClient
      @EnableDiscoveryClient//范围更大
      public class ConsumerApplication {
              
              
          public static void main(String[] args) {
              
              
              SpringApplication.run(ConsumerApplication.class);
          }
      
          @Bean
          public RestTemplate restTemplate() {
              
              
              return new RestTemplate();
          }
      }
      
  5. Eureka has its own ribbon, which is also a component in spring cloud, and its function is to achieve load balancing.

    • Start the provider on two ports respectively;

    • Accessing the consumer service, you can observe that the load balancing method is round-robin, and the other is random. Add the annotation @LoadBalanced to the method of injecting restTemplate into the consumer's startup class.

    • package com.zhong.consumer.controller;
      
      import com.zhong.consumer.pojo.User;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.PathVariable;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      import org.springframework.web.client.RestTemplate;
      
      /**
       * @author 华韵流风
       * @ClassName ProviderController
       * @Date 2021/10/15 15:54
       * @packageName com.zhong.provider.controller
       * @Description TODO
       */
      @RestController
      @RequestMapping("/consumer")
      public class ConsumerController {
              
              
      
          @Autowired
          private RestTemplate restTemplate;
      
          /*@Autowired
          private DiscoveryClient discoveryClient;*/
      
          @GetMapping("/user/{id}")
          public User user(@PathVariable String id) {
              
              
              //访问provider服务,得到user数据
      //        return restTemplate.getForObject("http://localhost:80/provider/user?id=" + id, User.class);
      
              /*List<ServiceInstance> instances = discoveryClient.getInstances("server-provider");
              String url = "http://" + instances.get(0).getHost() + ":" + instances.get(0).getPort();
              System.out.println(url);
              return restTemplate.getForObject(url + "/provider/user?id=" + id, User.class);*/
      
              return restTemplate.getForObject("http://server-provider/provider/user?id=" + id, User.class);
          }
      }
      
  6. Build a highly available registration center and eureka cluster.

    • The registration center can register itself or register with the other party. In a cluster environment, each server copies the registration information to each other. If the entire cluster fails, each client copies all the data of the registration center. At this time The whole project still works fine.

    • server:
        port: 10087(6)
      spring:
        application:
          name: server-eureka
      eureka:
        client:
          service-url:
            defaultZone: http://localhost:10086(7)/eureka
      
    • server:
        port: 8081
      spring:
        application:
          name: server-consumer
      eureka:
        client:
          service-url:
            defaultZone: http://localhost:10086/eureka,http://localhost:10087/eureka
      

4. Service fault tolerance and circuit breaker

  1. The so-called fault tolerance means that when some microservices cannot provide normal services, the whole system can still work normally.

    • Service avalanche, when a service fails to work, other services that call it will also fail to work, until a large number of services stop.
  2. There are two main ways to solve the avalanche, one is service degradation, and the other is circuit breaker.

    • Service downgrade, that is, replace the current non-working service with another service, and stop the current service if the current service is not the main service. A more typical approach is to return a message telling the other party that the service cannot work when accessing a degraded service.
    • Service fusing, when the service cannot work normally, temporarily disconnect the request, and then try to see if the service is normal after a period of time, and resume the service if it is normal. There are three states, one is open (open the fuse), the other is close (close the fuse, which is a normal state), and the third is half open (half open, trial stage).
  3. Hystrix (porcupine, with self-protection function), is one of the components of spring cloud, which can realize service degradation and fuse.

    • Its functions are implemented on the consumer. When the provider cannot provide services normally, the consumer is used to implement degradation and fuse.

    • use:

      • <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        
      • Add the annotation @EnableCircuitBreaker.

      • Note that @SpringCloudApplication has the functions of @SpringBootApplication, @EnableDiscoveryClient, @EnableCircuitBreaker three annotations.

      • Add @HystrixCommand(fallbackMethod = "method name") to the request method of the controller, which has the function of downgrading and fusing. The attribute value of fallbackMethod is a method name in this class. The parameters and return value of the method are required to be the same as the original method. When the service accessed by the original method cannot work normally, the system will switch to execute the method, which is the main reason for service degradation. practice. A message can be returned in this method.

      • When the provider's response time is greater than 1s, the service is degraded, and this 1s is the default value.

    • To realize the fuse of the service, mainly observe the transition of the three states. (Some configuration items are not prompted)

      • circuitBreaker:
          requestVolumeThreshold: 10
          sleepWindowInMilliseconds: 10000
          errorThresholdPercentage: 50
        
      • The effect of the above configuration is that when more than 50% of the 10 consecutive requests fail to work normally, it will enter the fuse state (open), and after 10 seconds, join the half-open state to try the request (half open), and if the attempt is successful, it will enter the close (fuse state) closure).

5. Feign

  • The original intention is to disguise, to convert the method call code (not elegant) written in the code to access the service provider into the method of using the interface, and use the method in the proxy object of the interface to send the request and receive the result. The camouflage is reflected in the use of interfaces on the surface, but in fact the bottom layer is still using the original method.

  • rely:

    • <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-openfeign</artifactId>
      </dependency>
      
    • Add the annotation @EnableFeignClients on the Application (that is, the startup class).

    • Create interface (key):

      • package com.zhong.consumer.client;
        
        import com.zhong.consumer.pojo.User;
        import org.springframework.cloud.openfeign.FeignClient;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.RequestParam;
        
        /**
         * @author 华韵流风
         * @ClassName ProviderClient
         * @Date 2021/10/19 10:35
         * @packageName com.zhong.consumer.client
         * @Description TODO
         */
        @FeignClient(value = "server-provider")
        public interface ProviderClient {
                  
                  
            /**
             * 示例方法
             *
             * @param id id
             * @return User
             */
            @GetMapping("/provider/user")
            User user(@RequestParam String id);
        }
        
        
    • Inject the interface object in the class that needs to make the request (in this way, there is no need to inject the RestTemplate):

      • package com.zhong.consumer.controller;
        
        import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
        import com.zhong.consumer.client.ProviderClient;
        import com.zhong.consumer.pojo.User;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.web.bind.annotation.GetMapping;
        import org.springframework.web.bind.annotation.PathVariable;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RestController;
        import org.springframework.web.client.RestTemplate;
        
        /**
         * @author 华韵流风
         * @ClassName ProviderController
         * @Date 2021/10/15 15:54
         * @packageName com.zhong.provider.controller
         * @Description TODO
         */
        @RestController
        @RequestMapping("/consumer")
        public class ConsumerController {
                  
                  
        
            /*@Autowired
            private RestTemplate restTemplate;*/
        
            @Autowired
            private ProviderClient providerClient;
        
            /*@Autowired
            private DiscoveryClient discoveryClient;*/
        
            @GetMapping("/user/{id}")
            @HystrixCommand(fallbackMethod = "callbackUser")
            public User user(@PathVariable String id) {
                  
                  
                //访问provider服务,得到user数据
        //        return restTemplate.getForObject("http://localhost:80/provider/user?id=" + id, User.class);
        
                /*List<ServiceInstance> instances = discoveryClient.getInstances("server-provider");
                String url = "http://" + instances.get(0).getHost() + ":" + instances.get(0).getPort();
                System.out.println(url);
                return restTemplate.getForObject(url + "/provider/user?id=" + id, User.class);*/
        
        //        return restTemplate.getForObject("http://server-provider/provider/user?id=" + id, User.class);
        
                if ("1".equals(id)) {
                  
                  
                    throw new RuntimeException();
                }
                return providerClient.user(id);
            }
        
            public User callbackUser(String id) {
                  
                  
                User user = new User();
                user.setId(id);
                user.setName("该服务暂时不可用,请稍后访问……");
                return user;
            }
        }
        
    • Feign integrates hystrix internally. If you use hystrix based on feign, you must add it to the configuration:

      • feign:
          hystrix:
            enabled: true
        
    • If feign is used, restTemplate will be used under the hood, and @LoadBalanced is used by default. So it still has the function of load balancing.

Six, zuul

  • It has the meaning of gateway, which is the gateway of microservices.
  • In the Internet, a gateway is a connection bridge between different LANs, through which devices in different network segments can access each other. Some access rules can be defined in the gateway.
  1. Why Microservices Need Gateways
    • If the front-end requests directly access microservices, each microservice has a unique interface and host, which will cause confusion in the address of the front-end access interface.
  2. For the front end, there should be a unified address writing form for accessing microservices. In addition, the permission code needs to be centralized or advanced to the front of openservice.
  3. All openservices must solve cross-domain problems, and microservice projects must be separated from the front and back ends.
  4. Multiple filters are provided inside the gateway, and different filters implement different functions. Custom filters are also provided. We can use it to complete permission-related functions, so that the code of permission is mentioned in the gateway, not written in openservice.
  • Implementation of the gateway

    • Create a gateway microservice

    • Add dependencies:

      • <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-netflix-zuul</artifactId>
        </dependency>
        
    • Add annotation: @EnableZuulProxy.

    • Add configuration, the focus is to get the name and access address of the application through eureka, and map the above name and access address. External requests can determine which service to access through mapping.

      • server:
          port: 10010
        spring:
          application:
            name: server-gateway
        eureka:
          client:
            service-url:
              defaultZone: http://localhost:10086/eureka
        #zuul:
        #  routes:
        #    #映射的id,可以随意写,但要保证唯一性
        #    server-provider:
        #      path: /server-provider/**
        #      serviceId: server-provider
        #    server-consumer:
        #      path: /server-consumer/**
        #      serviceId: server-consumer
        
        #简便写法
        zuul:
          routes:
            server-provider: /server-provider/**
            server-consumer: /server-consumer/**
          #访问前缀
          prefix: /web
        
      • Access with prefix: <http://localhost:10010/web/server-provider/provider/user?id=2>

      • The more omitted writing method is to write nothing, and the path defaults to /application name/**

  • Gateway filter:

    1. The gateway has a variety of built-in filters, all of which implement the IZuulFilter interface, and each of them plays a different role.

    2. If you need to implement a custom filter, you also need to inherit the ZullFilter abstract class and override related methods.

      • package com.zhong.gateway.filter;
        
        import com.netflix.zuul.ZuulFilter;
        import com.netflix.zuul.exception.ZuulException;
        import org.springframework.stereotype.Component;
        
        /**
         * @author 华韵流风
         * @ClassName MyFilter
         * @Date 2021/10/19 15:06
         * @packageName com.zhong.gateway.filter
         * @Description TODO
         */
        @Component
        public class MyFilter extends ZuulFilter {
                  
                  
            @Override
            public String filterType() {
                  
                  
                //前置过滤
                return "pre";
            }
        
            @Override
            public int filterOrder() {
                  
                  
                //返回执行顺序,数字越小越先执行
                return 0;
            }
        
            @Override
            public boolean shouldFilter() {
                  
                  
                //是否执行本过滤器
                return true;
            }
        
            @Override
            public Object run() throws ZuulException {
                  
                  
                //实现过滤器功能的方法
                System.out.println("filter run");
                return null;
            }
        }
        
    3. Example of front-end filtering:

      • package com.tensquare.web.filter;
        
        import com.netflix.zuul.ZuulFilter;
        import com.netflix.zuul.context.RequestContext;
        import com.netflix.zuul.exception.ZuulException;
        import org.springframework.stereotype.Component;
        
        import javax.servlet.http.HttpServletRequest;
        
        /**
         * @author 华韵流风
         * @ClassName WebFilter
         * @Date 2021/10/20 17:11
         * @packageName com.tensquare.web.filter
         * @Description TODO
         */
        @Component
        public class WebFilter extends ZuulFilter {
                  
                  
            @Override
            public String filterType() {
                  
                  
        //        pre :可以在请求被路由之前调用
        //        route :在路由请求时候被调用
        //        post :在route和error过滤器之后被调用
        //        error :处理请求时发生错误时被调用
                return "pre";
            }
        
            @Override
            public int filterOrder() {
                  
                  
                return 0;
            }
        
            @Override
            public boolean shouldFilter() {
                  
                  
                return true;
            }
        
            @Override
            public Object run() throws ZuulException {
                  
                  
                System.out.println("zuul的过滤器已执行……");
        
                //向header中添加鉴权令牌
                RequestContext requestContext = RequestContext.getCurrentContext();
                HttpServletRequest request = requestContext.getRequest();
                String authorization = request.getHeader("Authorization");
                if (authorization != null) {
                  
                  
                    requestContext.addZuulRequestHeader("Authorization", authorization);
                }
                return null;
            }
        }
        
      • server:
          port: 10020
        spring:
          application:
            name: tensquare-web
        eureka:
          client:
            service-url:
              defaultZone: http://localhost:10086/eureka
        zuul:
          routes:
            tensquare-gathering: /gathering/**
            tensquare-article: /article/**
            tensquare-base: /base/**
            tensquare-friend: /friend/**
            tensquare-qa: /qa/**
            tensquare-recruit: /recruit/**
            tensquare-spit: /spit/**
            tensquare-user: /user/**
            tensquare-search: /search/**
          sensitive-headers:
            - Cookie,Set-Cookie,Authorization #集合写法之一
        
    4. backend filtering example

      • package com.tensquare.manager.filter;
        
        import com.netflix.zuul.ZuulFilter;
        import com.netflix.zuul.context.RequestContext;
        import com.netflix.zuul.exception.ZuulException;
        import com.tensquare.utils.JwtUtil;
        import io.jsonwebtoken.Claims;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.stereotype.Component;
        
        import javax.servlet.http.HttpServletRequest;
        
        /**
         * @author 华韵流风
         * @ClassName WebFilter
         * @Date 2021/10/20 17:11
         * @packageName com.tensquare.web.filter
         * @Description TODO
         */
        @Component
        public class ManagerFilter extends ZuulFilter {
                  
                  
        
            @Autowired
            private JwtUtil jwtUtil;
        
            @Override
            public String filterType() {
                  
                  
        //        pre :可以在请求被路由之前调用
        //        route :在路由请求时候被调用
        //        post :在route和error过滤器之后被调用
        //        error :处理请求时发生错误时被调用
                return "pre";
            }
        
            @Override
            public int filterOrder() {
                  
                  
                return 0;
            }
        
            @Override
            public boolean shouldFilter() {
                  
                  
                return true;
            }
        
            @Override
            public Object run() throws ZuulException {
                  
                  
                System.out.println("zuul的过滤器已执行……");
        
                //向header中添加鉴权令牌
                RequestContext requestContext = RequestContext.getCurrentContext();
                HttpServletRequest request = requestContext.getRequest();
        
                if ("OPTIONS".equals(request.getMethod())) {
                  
                  
                    return null;
                }
                String url = request.getRequestURL().toString();
                if (url.indexOf("/admin/login") > 0) {
                  
                  
                    System.out.println("登陆页面" + url);
                    return null;
                }
                //获取头信息
                String authHeader = request.getHeader("Authorization");
                if (authHeader != null && authHeader.startsWith("Bearer ")) {
                  
                  
                    String token = authHeader.substring(7);
                    Claims claims = jwtUtil.parseJWT(token);
                    if (claims != null) {
                  
                  
                        if ("admin".equals(claims.get("roles"))) {
                  
                  
                            requestContext.addZuulRequestHeader("Authorization", authHeader);
                            System.out.println("token 验证通过,添加了头信息" + authHeader);
                            return null;
                        }
                    }
                }
                //终止运行
                requestContext.setSendZuulResponse(false);
                //http状态码
                requestContext.setResponseStatusCode(401);
                requestContext.setResponseBody("无权访问");
                requestContext.getResponse().setContentType("text/html;charset=UTF‐8");
        
                return null;
            }
        }
        
      • server:
          port: 10010
        spring:
          application:
            name: tensquare-manager
        eureka:
          client:
            service-url:
              defaultZone: http://localhost:10086/eureka
        zuul:
          routes:
            tensquare-gathering: /gathering/**
            tensquare-article: /article/**
            tensquare-base: /base/**
            tensquare-friend: /friend/**
            tensquare-qa: /qa/**
            tensquare-recruit: /recruit/**
            tensquare-spit: /spit/**
            tensquare-user: /user/**
          sensitive-headers: [Cookie,Authorization,Set-Cookie]
        jwt:
          config:
            ttl: 3600000
            key: zhong
        

7. Monitoring

  1. A monitoring dashboard for the circuit breaking function is provided in the hystrix component.

  2. The monitoring object must be a microservice using hystrix.

  3. A separate monitoring microservice must be created.

  4. Implementation steps:

    • Add dependencies:

      • <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        
    • Configuration:

      • management:
          endpoints:
            web:
              exposure:
                include: hystrix.stream
        
    • Annotation: @EnableHystrixDashboard

    • Observation results:

      • <http://localhost:8081/actuator/hystrix.stream>
      • <http://localhost:8081/consumer/user/2>

8. Centralized configuration component SpringCloudConfig

  1. gitee

    • Create a configuration center microservice

    • File naming rules: {application}-{profile}.yml or {application}-{profile}.properties

    • rely:

      • <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        
    • Annotation: @EnableConfigServer

    • Configuration:

      • server:
          port: 12000
        spring:
          application:
            name: server-config
          cloud:
            config:
              server:
                git:
                  uri: https://gitee.com/hylf/tensquare.git
                  username: #私人仓库需要账号密码
                  password: ********
        
    • Consumer side:

    • rely:

      • <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        
    • Change the original configuration name to bootstrap.yml, and the configuration content is:

      • spring:
          cloud:
            config:
              name: base
              profile: dev
              label: master
              uri: http://127.0.0.1:12000
        

Guess you like

Origin blog.csdn.net/qq_44628734/article/details/121053763