zoukankan      html  css  js  c++  java
  • SpringCloud

    一、微服务架构

    1.1、什么是分布式

      将不同模块部署在不同服务器上

      作用:分布式解决网站高并发带来的问题

    1.2、什么是集群

      多台服务器部署相同应用构成一个集群

      作用:通过负载均衡设备共同对外提供服务

    1.3、什么是RPC

      RPC 的全称是 Remote Procedure Call ,是一种进程间通信方式。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数。

    1.4、restful、soap、RPC

      (1)RESTful是一种架构设计风格,提供了设计原则和约束条件,而不是架构。而满足这些约束条件和原则的应用程序或设计就是 RESTful架构或服务。
      (2)SOAP,简单对象访问协议是一种数据交换协议规范,是一种轻量的、简单的、基于XML的协议的规范。

        SOAP协议和HTTP协议一样,都是底层的通信协议,只是请求包的格式不同而已,SOAP包是XML格式的。
        SOAP的消息是基于xml并封装成了符合http协议,因此,它符合任何路由器、 防火墙或代理服务器的要求。
        SOAP可以使用任何语言来完成,只要发送正确的soap请求即可,基于soap的服务可以在任何平台无需修改即可正常使用。
      (3)RPC就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果。
        RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯)
        RPC 是一个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的工作方式)
        RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)。

    1.5、RPC远程调用框架

      (1)RMI实现,利用java.rmi包实现,基于Java远程方法协议(Java Remote Method Protocol) 和java的原生序列化。 
      (2)Hessian,是一个轻量级的remotingonhttp工具,使用简单的方法提供了RMI的功能。 基于HTTP协议,采用二进制编解码。 
      (3)thrift是一种可伸缩的跨语言服务的软件框架。thrift允许你定义一个描述文件,描述数据类型和服务接口。依据该文件,编译器方便地生成RPC客户端和服务器通信代码。

      (4)SpringCloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。

    1.6、什么是SOA

      面向服务架构,它将业务系统分解为多个组件,让每个组件都独立提供离散,自治,可复用的服务能力。通过服务的组合和编排来实现上层的业务流程

      作用:简化维护,降低整体风险,伸缩灵活

    1.7、什么是微服务

      架构设计概念,各服务间隔离(分布式也是隔离),自治(分布式依赖整体组合)其它特性(单一职责,边界,异步通信,独立部署)是分布式概念的跟严格执行

      SOA到微服务架构的演进过程

       作用:各服务可独立应用,组合服务也可系统应用(巨石应用[monolith]的简化实现策略-平台思想)

    二、SpringCloud

      SpringCloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。

      SpringCloud就是一个RPC微服务框架,提供注册服务、发现服务、断路器、网关、自动配置。Eureka(注册中心)、ribbon(负载均衡)、feign(http协议调用工具)。底层通过HTTPClient进行封装。

    三、服务的注册与发现(Eureka)

    3.1、eureka是一个服务注册和发现模块。创建一个eurekaServer项目

    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.6.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.stu</groupId>
        <artifactId>eureka-server-demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>eureka-server-demo</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>

      配置application.yml文件

    server:
      port: 8761
    eureka:
      instance:
        hostname: localhost
      client:
        registerWithEureka: false
        fetchRegistry: false
        serviceUrl:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    1. eureka.client.registerWithEureka=true  #是否将自身注册  
    2. eureka.client.fetchRegistry=false    #如果为true,启动时报警. 

      项目启动成功后,访问http://localhost:8761,成功即可。

    3.2、创建服务提供者项目

      创建一个服务提供者 (eureka client),当client向server注册时,它会提供一些元数据,例如主机和端口,URL,主页等。Eureka server 从每个client实例接收心跳消息。 如果心跳超时,则通常将该实例从注册server中删除。

      创建项目EurekaClient

    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.6.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.stu</groupId>
        <artifactId>eureka-client</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>eureka-client</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
            <spring-cloud.version>Greenwich.SR1</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>

      配置application.yml配置

    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    server:
      port: 8763
    spring:
      application:
        name: service-hi

      发布服务,通过注解@EnableEurekaClient 表明自己是一个eurekaclient。

    @SpringBootApplication
    @EnableEurekaClient
    public class ServiceHiApplication {
      。。。
    }

      需要指明spring.application.name,这样eureka server启动后,http://localhost:8762/hi?name=xxx,即可调用注册的服务。

    四、服务消费者

      在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务的通讯是基于http restful的。Spring cloud有两种服务调用方式,一种是ribbon+restTemplate,另一种是feign。

     4.1、什么是ribbon

      ribbon是一个负载均衡客户端,可以很好的控制htt和tcp的一些行为。Feign默认集成了ribbon。

      创建一个消费者项目,service-ribbon

    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.6.RELEASE</version>
            <relativePath /> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-ribbon</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix</artifactId>
            </dependency>
    
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Dalston.RC1</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>

      application.yml配置

    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    server:
      port: 8764
    spring:
      application:
        name: service-ribbon

       启动类

      在工程的启动类中,通过@EnableDiscoveryClient向服务中心注册;并且向程序的ioc注入一个bean: restTemplate;并通过@LoadBalanced注解表明这个restRemplate开启负载均衡的功能。

    @EnableAutoConfiguration
    @ComponentScan(basePackages={"com.stu"})
    @EnableDiscoveryClient
    public class ServiceRibbonApplication {
        public static void main(String[] args) {
            SpringApplication.run(ServiceRibbonApplication.class, args);
        }
    
        @Bean
        @LoadBalanced
        RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }

      编写一个service

    @Service
    public class HelloService {
    @Autowired
    RestTemplate restTemplate;
    public String hiService(String name) {
      return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
    }
    }

       编写controller

    @RestController
    public class RibbonController {
        @Autowired
        private HelloService helloService;
         @RequestMapping("/hi")
        public String hi(String name) {
            return helloService.hi(name);
        }
    
    }

      测试,将eureka server启动,端口为8761。将service-hi启动两次,端口分别为8762、8763。再将service-ribbon启动,端口为8764.

      访问http://localhost:8764/hi?name=forezp,浏览器会交替返回端口8762/8763。这说明当我们通过调用restTemplate.getForObject(“http://SERVICE-HI/hi?name=“+name,String.class)方法时,已经做了负载均衡,访问了不同的端口的服务实例。

         

    • 一个服务注册中心,eureka server,端口为8761
    • service-hi工程跑了两个实例,端口分别为8762,8763,分别向服务注册中心注册
    • sercvice-ribbon端口为8764,向服务注册中心注册
    • 当sercvice-ribbon通过restTemplate调用service-hi的hi接口时,因为用ribbon进行了负载均衡,会轮流的调用service-hi:8762和8763 两个端口的hi接口;
    • @LoadBalanced注解表明这个restRemplate开启负载均衡的功能。

    五、服务消费者(Feign)

      Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。

      简而言之:

    • Feign 采用的是基于接口的注解
    • Feign 整合了ribbon

       创建项目service-feign

    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.6.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
    <!-- SpringCloud 整合 Feign -->
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.RC1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>

      配置application.yml

    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    server:
      port: 8765
    spring:
      application:
        name: service-feign
        

      定义一个feign接口

    @FeignClient(value = "service-hi")
    public interface SchedualServiceHi {
        @RequestMapping(value = "/hi", method = RequestMethod.GET)
        String sayHiFromClientOne(@RequestParam(value = "name") String name);
    }

      定义一个controller,hi的API接口

    @RestController
    public class IndexController {
    
        @Autowired
        private FeignService feignService;
    
        @RequestMapping("/hi")
        public String hi(String name) {
            return feignService.hi(name);
        }
    }

      启动类

    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients
    public class SericeFeignApp {
        public static void main(String[] args) {
            SpringApplication.run(SericeFeignApp.class, args);
        }
    }

      演示:同样启动2个service-hi,访问http://localhost:8765/hi?name=forezp,会交替返回2个端口。说明负载均衡生效。feign默认集成ribbon。

     六、断路器

      在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。

      为了解决这个问题,业界提出了断路器模型。

     6.1、什么是断路器

      Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。在微服务架构中,一个请求需要调用多个服务是非常常见的。较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystric是5秒20次)断路器将会被打开。断路打开后,可用避免连锁故障,fallback方法可以直接返回一个固定值。

    6.2、在ribbon项目中加入断路器

      pom中引入依赖

    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>

       改造HelloService类,在hiService方法上加上@HystrixCommand注解。该注解对该方法创建了熔断器的功能,并指定了fallbackMethod熔断方法,熔断方法直接返回了一个字符串,字符串为”hi,”+name+”,sorry,error!”

    @Service
    public class HelloService {
        @Autowired
        RestTemplate restTemplate;
    
        @HystrixCommand(fallbackMethod = "hiError")
        public String hiService(String name) {
            return restTemplate.getForObject("http://SERVICE-HI/hi?name=" + name, String.class);
        }
    
        public String hiError(String name) {
            return"hi," + name + ",sorry,error!";
        }
    }

      演示:关闭service-hi工程,访问http://localhost:8764/hi?name=forezp,浏览器会显示:hi ,forezp,orry,error!

      这就说明当 service-hi 工程不可用的时候,service-ribbon调用 service-hi的API接口时,会执行快速失败,直接返回一组字符串,而不是等待响应超时,这很好的控制了容器的线程阻塞。

     6.3、在feign中使用断路器

      Feign是自带断路器的,在D版本的Spring Cloud中,它没有默认打开。需要在配置文件中配置打开它,在配置文件加以下代码:feign.hystrix.enabled=true

      基于service-feign工程进行改造,只需要在FeignClient的SchedualServiceHi接口的注解中加上fallback的指定类就行了:

    @FeignClient(value = "service-hi",fallback=SchedualServiceHiHystric.class)
    public interface SchedualServiceHi {
        @RequestMapping(value = "/hi", method = RequestMethod.GET)
        String sayHiFromClientOne(@RequestParam(value = "name") String name);
    }

      SchedualServiceHiHystric需要实现SchedualServiceHi接口,并注入到Ioc容器中,代码如下:

    @Component
    public class SchedualServiceHiHystric implements SchedualServiceHi {
        public String sayHiFromClientOne(String name) {
            return "sorry " + name;
        }
    }

       application.yml中开启断路器

    feign:
      hystrix:
        enabled: true

     6.4、Hystrix Dashboard (断路器:Hystrix仪表盘)

       基于service-ribbon 改造,Feign的改造和这一样

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
            </dependency>

      在主程序启动类中加入@EnableHystrixDashboard注解,开启hystrixDashboard。

      打开浏览器:访问http://localhost:8764/hystrix

    七、使用Zuul构建API Gateway

    7.1、什么是API Gateway?

      在Spring Cloud微服务系统中,一种常见的负载均衡方式是,客户端的请求首先经过负载均衡(zuul、Ngnix),再到达服务网关(zuul集群),然后再到具体的服务。

    7.2、说明是Zuul

      路由在微服务架构的一个组成部分。例如,/可以映射到您的Web应用程序,/ api / users映射到用户服务,并且/ api / shop映射到商店服务。Zuul是Netflix的基于JVM的路由器和服务器端负载均衡器 

       其功能包括:验证、见解、压力测试、金丝雀测试、动态路由、服务迁移、减载、安全、静态响应处理、主动/主动流量管理

      Zuul的规则引擎允许规则和过滤器基本上用任何JVM语言编写,内置支持Java和Groovy。

      创建service-zuul工程

    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
    <relativePath/><!-- lookup parent from repository -->
    </parent>
    
    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    </properties>
    
    <dependencies>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zuul</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>
    </dependencies>
    
    <dependencyManagement>
    <dependencies>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-dependencies</artifactId>
    <version>Dalston.RC1</version>
    <type>pom</type>
    <scope>import</scope>
    </dependency>
    </dependencies>
    </dependencyManagement>
    
    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    </plugins>
    </build>
    
    <repositories>
    <repository>
    <id>spring-milestones</id>
    <name>Spring Milestones</name>
    <url>https://repo.spring.io/milestone</url>
    <snapshots>
    <enabled>false</enabled>
    </snapshots>
    </repository>
    </repositories>

      启动类:在其入口applicaton类加上注解@EnableZuulProxy,开启zuul的功能

    @EnableZuulProxy
    @EnableEurekaClient
    @SpringBootApplication
    publicclassServiceZuulApplication {

      application.yml

    eureka:
      client:
        serviceUrl:
          defaultZone: http://localhost:8761/eureka/
    server:
      port: 8769
    spring:
      application:
        name: service-zuul
    zuul:
      routes:
        api-a:
         path: /api-a/**
         service-id: service-ribbon
        api-b:
         path: /api-b/**
         service-id: service-feign   
            

      首先指定服务注册中心的地址为http://localhost:8761/eureka/,服务的端口为8769,服务名为service-zuul;以/api-a/ 开头的请求都转发给service-ribbon服务;以/api-b/开头的请求都转发给service-feign服务;

      访问:http://localhost:8769/api-a/hi?name=forezp ;浏览器显示:hiforezp,i am from port:8762

    7.3、服务器过滤

      zuul不仅只是路由,并且还能过滤,做一些安全验证

    @Component
    public class MyFilter extends ZuulFilter{
    
    private static Logger log = LoggerFactory.getLogger(MyFilter.class);
    @Override
    public String filterType() {
    return "pre";
        }
    
    @Override
    public intfilter Order() {
    return 0;
        }
    
    @Override
    public boolean shouldFilter() {
        return true;
        }
    
    @Override
    public Object run() {
    RequestContext ctx = RequestContext.getCurrentContext();
    HttpServletRequest request = ctx.getRequest();
    log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
    Object accessToken = request.getParameter("token");
    if(accessToken == null) {
    log.warn("token is empty");
    ctx.setSendZuulResponse(false);
    ctx.setResponseStatusCode(401);
    try {
    ctx.getResponse().getWriter().write("token is empty");
                }catch (Exception e){}
    
    return null;
            }
            log.info("ok");
    return null;
        }
    }
    • filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:
      • pre:路由之前
      • routing:路由之时
      • post:路由之后
      • error:发送错误调用
      • filterOrder:过滤的顺序
      • shouldFilter:这里可以写逻辑判断,是否要过滤,本文true,永远过滤。
      • run:过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问。

      这时访问:http://localhost:8769/api-a/hi?name=forezp ;网页显示:token is empty

     八、分布式配置中心

      分布式配置中心(Spring Cloud Config),在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件spring cloud config,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。在spring cloud config组件中,分两个角色,一是config server,二是config client。

    8.1、构建ConfigServer

      创建一个spring-boot项目,取名为config-server,其pom.xml

    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.6.RELEASE</version>
            <relativePath/><!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-config-server</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-eureka</artifactId>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Camden.SR6</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>

      启动类加上类加上@EnableConfigServer

      application配置

    spring.application.name=config-server
    server.port=8888
    
    spring.cloud.config.server.git.uri=https://gitee.com/itmayi/itmayiedu2.git
    spring.cloud.config.server.git.searchPaths=/woniusky/springcloud_server.git
    spring.cloud.config.label=master
    spring.cloud.config.server.git.username=
    spring.cloud.config.server.git.password=
    
    eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
    • spring.cloud.config.server.git.uri:配置git仓库地址
    • spring.cloud.config.server.git.searchPaths:配置仓库路径
    • spring.cloud.config.label:配置仓库的分支
    • spring.cloud.config.server.git.username:访问git仓库的用户名
    • spring.cloud.config.server.git.password:访问git仓库的用户密码

      启动程序:访问http://localhost:8888/foo/dev

    {"name":"foo","profiles":["dev"],"label":"master",
    "version":"792ffc77c03f4b138d28e89b576900ac5e01a44b","state":null,"propertySources":[]}

    8.2、构建ConfigClient

      重新创建一个springboot项目,取名为config-client,其pom文件 

    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.6.RELEASE</version>
            <relativePath/><!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-config</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Dalston.RC1</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
        <repositories>
            <repository>
                <id>spring-milestones</id>
                <name>Spring Milestones</name>
                <url>https://repo.spring.io/milestone</url>
                <snapshots>
                    <enabled>false</enabled>
                </snapshots>
            </repository>
        </repositories>

      配置文件bootstrap.properties

    spring.application.name=config-client
    spring.cloud.config.label=master
    spring.cloud.config.profile=dev
    #spring.cloud.config.uri= http://localhost:8888/
    eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
    spring.cloud.config.discovery.serviceId=config-server
    server.port=8881
    • spring.cloud.config.label指明远程仓库的分支
    • spring.cloud.config.profile
    • spring.cloud.config.uri= http://localhost:8888/ 指明配置服务中心的网址
      • dev开发环境配置文件
      • test测试环境
      • pro正式环境

      写一个API接口“/hi” 

    @RestController
    public class ConfigClientApplication {
        @Value("${foo}")
        String foo;
    
        @RequestMapping(value = "/hi")
        public String hi() {
            return foo;
        }
    }

      访问http://localhost:8881/hi,网页显示:foo version 3

  • 相关阅读:
    6389. 【NOIP2019模拟2019.10.26】小w学图论
    6383. 【NOIP2019模拟2019.10.07】果实摘取
    三分查找求极值
    51Nod 1278 相离的圆
    51 Nod 1092 回文字符串
    关于原根(来自百度百科)
    Hdu 1358 Period
    最大子矩阵和
    51 Nod 1072 威佐夫游戏
    The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online(2018 青岛网络预选赛)
  • 原文地址:https://www.cnblogs.com/woniusky/p/11052652.html
Copyright © 2011-2022 走看看