Spring Cloud 微服務框架之服務註冊與發現

Spring Cloud介紹

Spring Cloud是一個相對比較新的微服務框架,2016才推出1.0的release版本. 雖然Spring Cloud時間最短, 但是相比Dubbo等RPC框架, Spring Cloud提供的全套的分佈式系統解決方案。

Spring Cloud 爲開發者提供了在分佈式系統(配置管理,服務發現,熔斷,路由,微代理,控制總線,一次性token,全居瑣,leader選舉,分佈式session,集羣狀態)中快速構建的工具,使用Spring Cloud的開發者可以快速的啓動服務或構建應用、同時能夠快速和雲平臺資源進行對接。

微服務架構

微服務可以在“自己的程序”中運行,並通過“輕量級設備與HTTP型API進行溝通”。關鍵在於該服務可以在自己的程序中運行。通過這一點我們就可以將服務公開與微服務架構(在現有系統中分佈一個API)區分開來。在服務公開中,許多服務都可以被內部獨立進程所限制。如果其中任何一個服務需要增加某種功能,那麼就必須縮小進程範圍。在微服務架構中,只需要在特定的某種服務中增加所需功能,而不影響整體進程。
微服務不需要像普通服務那樣成爲一種獨立的功能或者獨立的資源。定義中稱,微服務是需要與業務能力相匹配,這種說法完全正確。不幸的是,仍然意味着,如果能力模型粒度的設計是錯誤的,那麼,我們就必須付出很多代價。如果你閱讀了Fowler的整篇文章,你會發現,其中的指導建議是非常實用的。在決定將所有組件組合到一起時,開發人員需要非常確信這些組件都會有所改變,並且規模也會發生變化。服務粒度越粗,就越難以符合規定原則。服務粒度越細,就越能夠靈活地降低變化和負載所帶來的影響。然而,利弊之間的權衡過程是非常複雜的,我們要在配置和資金模型的基礎上考慮到基礎設施的成本問題。

服務註冊與發現

接下來我們通過實際案例來看看如何使用Spring Cloud搭建服務註冊與發現模塊,案例中核心內容就是服務發現模塊:Eureka

1、首先創建“服務註冊中心”

(1)創建一個Maven工程,並在pom.xml中引入需要的依賴內容:

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.3.5.RELEASE</version>
	<relativePath/>
</parent>
<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<java.version>1.7</java.version>
</properties>
<dependencies>
	<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-server</artifactId>
	</dependency>
</dependencies>
<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-dependencies</artifactId>
			<version>Brixton.RELEASE</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>
(2)通過@EnableEurekaServer註解啓動一個服務註冊中心提供給其他應用進行對話。這一步非常的簡單,只需要在一個普通的Spring Boot應用中添加這個註解就能開啓此功能,創建一個Application.java,如下所示:

package com.wys;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class Application {
	public static void main(String[] args) {
		new SpringApplicationBuilder(Application.class).web(true).run(args);
	}
}
(3)在默認設置下,該服務註冊中心也會將自己作爲客戶端來嘗試註冊它自己,所以我們需要禁用它的客戶端註冊行爲,只需要在application.properties中問增加如下配置:
server.port=1111
#eureka.instance.hostname=localhost
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
至此,簡單的服務註冊就搭建好了,項目整體結構如下:


現在啓動工程(Application.java),訪問:http://localhost:1111/     (注意這裏的1111是自己在application.properties文件中設置的端口號)

此時,可以看到下面的頁面,其中還沒有發現任何服務


該工程可參考:eureka-server

(4)創建“服務提供方”

接下來我們創建提供服務的客戶端,並向服務註冊中心註冊自己。

假設我們有一個提供計算功能的微服務模塊,我們實現一個RESTful API,通過傳入兩個參數a和b,最後返回a + b的結果。

首先,創建一個Maven工程,在pom.xml文件中加入依賴,如下所示。

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.3.5.RELEASE</version>
	<relativePath/>
</parent>
<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<java.version>1.7</java.version>
</properties>
<dependencies>
	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-eureka</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>Brixton.RELEASE</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>
(5)實現/add請求處理接口,通過DiscoveryClient對象,在日誌中打印出服務實例的相關內容

package com.wys.web;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ComputeController {
	private final Logger logger=Logger.getLogger(getClass());
	@Autowired
	private DiscoveryClient client;
	@RequestMapping(value="/add",method=RequestMethod.GET)
	public Integer add(@RequestParam Integer a,@RequestParam Integer b){
		ServiceInstance instance=client.getLocalServiceInstance();
		Integer r=a+b;
		logger.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r);
		return r;
	}
}
(6)在主類中通過加上@EnableDiscoveryClient註解,該註解能激活Eureka中的DiscoveryClient實現,才能實現Controller中對服務信息的輸出。
package com.wys;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class ComputeServiceApplication {

	public static void main(String[] args) {
		new SpringApplicationBuilder(ComputeServiceApplication.class).web(true).run(args);
	}

}
(7)完成了服務內容的實現之後,再繼續對application.properties做一些配置工作,具體如下:

spring.application.name=compute-service
server.port=2222
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
通過spring.application.name屬性,我們可以指定微服務的名稱後續在調用的時候只需要使用該名稱就可以進行服務的訪問。
eureka.client.serviceUrl.defaultZone屬性對應服務註冊中心的配置內容,指定服務註冊中心的位置。
爲了在本機上測試區分服務提供方和服務註冊中心,使用server.port屬性可以設置不同的端口。

至此,“服務提供方”已經創建好了,整體項目結構如下:

啓動該工程之前,先啓動剛剛創建的服務註冊中心(eureka-server中的Application.java)

訪問:http://localhost:1111/    可以看到,我們定義的服務被註冊了。


該工程可參考:compute-service

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章