SpringCloud

1、微服務架構java

1.一、什麼是分佈式git

  將不一樣模塊部署在不一樣服務器上web

  做用:分佈式解決網站高併發帶來的問題spring

1.二、什麼是集羣sql

  多臺服務器部署相同應用構成一個集羣bootstrap

  做用:經過負載均衡設備共同對外提供服務api

1.三、什麼是RPC瀏覽器

  RPC 的全稱是 Remote Procedure Call ,是一種進程間通訊方式。它容許程序調用另外一個地址空間(一般是共享網絡的另外一臺機器上)的過程或函數。安全

1.四、restful、soap、RPCspringboot

  (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.五、RPC遠程調用框架

  (1)RMI實現,利用java.rmi包實現,基於Java遠程方法協議(Java Remote Method Protocol) 和java的原生序列化。 
  (2)Hessian,是一個輕量級的remotingonhttp工具,使用簡單的方法提供了RMI的功能。 基於HTTP協議,採用二進制編解碼。 
  (3)thrift是一種可伸縮的跨語言服務的軟件框架。thrift容許你定義一個描述文件,描述數據類型和服務接口。依據該文件,編譯器方便地生成RPC客戶端和服務器通訊代碼。

  (4)SpringCloud 爲開發人員提供了快速構建分佈式系統的一些工具,包括配置管理、服務發現、斷路器、路由、微代理、事件總線、全局鎖、決策競選、分佈式會話等等。

1.六、什麼是SOA

  面向服務架構,它將業務系統分解爲多個組件,讓每一個組件都獨立提供離散,自治,可複用的服務能力。經過服務的組合和編排來實現上層的業務流程

  做用:簡化維護,下降總體風險,伸縮靈活

1.七、什麼是微服務

  架構設計概念,各服務間隔離(分佈式也是隔離),自治(分佈式依賴總體組合)其它特性(單一職責,邊界,異步通訊,獨立部署)是分佈式概念的跟嚴格執行

  SOA到微服務架構的演進過程

   做用:各服務可獨立應用,組合服務也可系統應用(巨石應用[monolith]的簡化實現策略-平臺思想)

2、SpringCloud

  SpringCloud 爲開發人員提供了快速構建分佈式系統的一些工具,包括配置管理、服務發現、斷路器、路由、微代理、事件總線、全局鎖、決策競選、分佈式會話等等。

  SpringCloud就是一個RPC微服務框架,提供註冊服務、發現服務、斷路器、網關、自動配置。Eureka(註冊中心)、ribbon(負載均衡)、feign(http協議調用工具)。底層經過HTTPClient進行封裝。

3、服務的註冊與發現(Eureka)

3.一、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.二、建立服務提供者項目

  建立一個服務提供者 (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,便可調用註冊的服務。

4、服務消費者

  在微服務架構中,業務都會被拆分紅一個獨立的服務,服務與服務的通信是基於http restful的。Spring cloud有兩種服務調用方式,一種是ribbon+restTemplate,另外一種是feign。

 4.一、什麼是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啓動兩次,端口分別爲876二、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開啓負載均衡的功能。

5、服務消費者(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。

 6、斷路器

  在微服務架構中,根據業務來拆分紅一個個的服務,服務與服務之間能夠相互調用(RPC),在Spring Cloud能夠用RestTemplate+Ribbon和Feign來調用。爲了保證其高可用,單個服務一般會集羣部署。因爲網絡緣由或者自身的緣由,服務並不能保證100%可用,若是單個服務出現問題,調用這個服務就會出現線程阻塞,此時如有大量的請求涌入,Servlet容器的線程資源會被消耗完畢,致使服務癱瘓。服務與服務之間的依賴性,故障會傳播,會對整個微服務系統形成災難性的嚴重後果,這就是服務故障的「雪崩」效應。

  爲了解決這個問題,業界提出了斷路器模型。

 6.一、什麼是斷路器

  Netflix開源了Hystrix組件,實現了斷路器模式,SpringCloud對這一組件進行了整合。在微服務架構中,一個請求須要調用多個服務是很是常見的。較底層的服務若是出現故障,會致使連鎖故障。當對特定的服務的調用的不可用達到一個閥值(Hystric是5秒20次)斷路器將會被打開。斷路打開後,可用避免連鎖故障,fallback方法能夠直接返回一個固定值。

6.二、在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.三、在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.四、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

7、使用Zuul構建API Gateway

7.一、什麼是API Gateway?

  在Spring Cloud微服務系統中,一種常見的負載均衡方式是,客戶端的請求首先通過負載均衡(zuul、Ngnix),再到達服務網關(zuul集羣),而後再到具體的服務。

7.二、說明是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.三、服務器過濾

  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

 8、分佈式配置中心

  分佈式配置中心(Spring Cloud Config),在分佈式系統中,因爲服務數量巨多,爲了方便服務配置文件統一管理,實時更新,因此須要分佈式配置中心組件。在Spring Cloud中,有分佈式配置中心組件spring cloud config,它支持配置服務放在配置服務的內存中(即本地),也支持放在遠程Git倉庫中。在spring cloud config組件中,分兩個角色,一是config server,二是config client。

8.一、構建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.二、構建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

相關文章
相關標籤/搜索