1. 程式人生 > >Spring Cloud學習(三)

Spring Cloud學習(三)

接上文繼續

注意!後續application.yml中的spring.application.name需使用駝峰命名或其他,名稱中不可存在符號,如provider-user,需改成providerUser,不然後面講到的Config元件中,git中的配置檔案命名也會帶-,然後就會出現無法自動載入配置的bug。

5、Config配置中心

5.1 配置Config Server

本次demo是在Windows上執行的,後續需要RabbitMQ來自動載入配置,所以Windows上要預先安裝RMQ,參看我的部落格

依賴如下

<dependencies>
		<dependency>
<groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 使用bus匯流排的方式通知所有的微服務配置檔案需要重新整理 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</
artifactId
>
</dependency> <!-- Spring Cloud Config Server --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> <!-- 配置中心監控 --> <!-- 在遠端git倉庫修改配置後需要觸發遠端git的webhook, 請求本地的/monitor介面來觸發修改,所以需要引入spring-cloud-config-monitor依賴 -->
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-monitor</artifactId> </dependency> <!-- Spring Cloud Eureka Client --> <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>

bootstrap.yml

解釋下這裡為什麼要改名為bootstrap,這裡涉及到一個先後順序,Spring Boot會先載入bootstrap.yml然後再載入application.yml。
server:
  port: 6001

eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka

spring:
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/BigYoungZhao/spring-cloud-config.git
          username: 你的碼雲賬號
          password: 你的碼雲密碼
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
  application:
    name: configServer6001
management:
  endpoints:
    web:
      exposure:
        include: "*"

啟動類

@SpringBootApplication
@EnableDiscoveryClient
@EnableConfigServer
public class ConfigServer6001Application {

	public static void main(String[] args) {
		SpringApplication.run(ConfigServer6001Application.class, args);
	}
}

檢查是否從git獲取到配置檔案

在這裡插入圖片描述

啟動Config Server專案,訪問http://localhost:6001/user-dev.yml

在這裡插入圖片描述

檢查monitor 介面是否可用,訪問http://localhost:6001/monitor

在這裡插入圖片描述

為什麼是訪問這個介面呢?來看看原始碼

在這裡插入圖片描述

spring-cloud-config-monitor包下,該包定義了目前支援通知提醒的方式。常用的支援gitee 、github 、gitlab這三種git的配置 。notifyByPath,顧名思義,該介面表示根據路徑通知服務的方法
@RequestMapping(method = RequestMethod.POST)
	public Set<String> notifyByPath(@RequestHeader HttpHeaders headers,
			@RequestBody Map<String, Object> request) {
		PropertyPathNotification notification = this.extractor.extract(headers, request);
		if (notification != null) {

			Set<String> services = new LinkedHashSet<>();

			for (String path : notification.getPaths()) {
				services.addAll(guessServiceName(path));
			}
			if (this.applicationEventPublisher != null) {
				for (String service : services) {
					log.info("Refresh for: " + service);
					this.applicationEventPublisher
							.publishEvent(new RefreshRemoteApplicationEvent(this,
									this.busId, service));
				}
				return services;
			}

		}
		return Collections.emptySet();
	}

5.2 配置micro-service(需要獲取配置的物件服務)

改造上一篇的一個微服務

依賴如下

<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<!-- 使用bus匯流排的方式通知所有的微服務配置檔案需要重新整理 -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-bus-amqp</artifactId>
		</dependency>

		<!-- Spring Cloud Config Client -->
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-config-client</artifactId>
		</dependency>

		<!-- Spring Cloud Eureka Client -->
		<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>

application.yml

server:
  port: 8001

bootstrap.yml

spring:
  cloud:
    config:
      name: user #對應git上的user-dev.yml中的user
      profile: dev #對應git上的user-dev.yml中的dev
      discovery:
        service-id: configServer6001 #Config Server中bootstrap.yml的spring.application.name
      uri: http://localhost:6001 #Config Server的訪問路徑,不寫這個直接報錯:Cannot determine embedded database driver class for database type NONE

啟動類

@SpringBootApplication
@EnableDiscoveryClient
public class ProviderUser8001Application {

	public static void main(String[] args) {
		SpringApplication.run(ProviderUser8001Application.class, args);
	}
}

寫個controller測試下

@RestController
@RefreshScope //重新整理範圍,必要,注意
public class UserController {

    @Value("${spring.datasource.url}")
    private String datasourceUrl;

    @GetMapping("/getDatasourceUrl")
    public String getDatasourceUrl() {
        return this.datasourceUrl;
    }

}

按順序啟動Eureka、Config Server、微服務,訪問http://localhost:8001/getDatasourceUrl

在這裡插入圖片描述

當我把user-dev.yml裡的資料庫改為test_prod時,再次去訪問http://localhost:8001/getDatasourceUrl,還是上圖的結果。

一旦修改,配置中心的資料是重新整理了,而微服務的配置資料只是在請求時獲取到,之後不會主動去重新拉取新的配置資料。只能靠 POST請求 http://localhost:6001/actuator/bus-refresh進行手動重新整理。這個主要是通過我們配置的RabbitMQ,將重新整理資料的訊息放到MQ,並被微服務消費,從而重新整理。

那麼該如何自動重新整理呢?

webhook機制,相當於一個回撥,在我們push時,呼叫這個介面。

在這裡插入圖片描述

注意:由於我們的工程在本機,外網無法訪問到你的服務,所以搞個內網穿透的工具(natapp)。