最近看《深入理解Spring Cloud微服務構建》是一書之中,發現書中所講網關是Zuul實現的,由於筆者學習的版本基本上是在spring5.0,springboot2.0以上實現,進而發現了spring官方網關gateway ,因此替代了書中所用Zuul網關,想知道gateway網關和Zuul區別的,網上自行查閱即可。
話不多說 上demo 結構目錄
由上而下依次是 eureka服務端,feign,網關服務,user-service,sleuth zipkin鏈路追蹤服務端,
整個核心流程圖大概如下
請求首先經過網關 gateway ----A----> feign ----B---- > user-service
A: gateway從eureka-server列表裏面拿到server_id再分發請求)
B: feign得到請求後 執行到feignclient,發現feignclient調用了user-service ,則feign再通過eureka-server去具體得到
user-service再去訪問。
zipkin-server 監聽跟蹤該請求的每個服務的響應情況,zipkin可採用http形式上傳消息,也可用rabbitmq ,kafka等。
都是基於springboot2.1.4版本,springcloud Greenwich 版本 ,筆者的上一篇博客《spring cloud Bus 代理 rabbitMQ 自動刷新配置》也是基於該版本,不過忘記貼入pom依賴,再次全部貼出
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
<zipkin-server.version>2.11.4</zipkin-server.version>
</properties>
<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>
1 eureka-server eureka服務端
eureka的搭建,話不多說
pom依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
resources 下面application.yml配置
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
spring:
application:
name: eureka-server
啓動類上加入 @EnableEurekaServer 註解
2 zipkin-server 鏈路追蹤的服務端
首先poml引入相關zipkin的依賴
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<!-- 鏈路追蹤的依賴服務 採用http上傳的模式,也可採用RabbitMq kafka來傳輸-->
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
<version>${zipkin-server.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- zipkinServer的ui依賴界面-->
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
<version>${zipkin-server.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
在application.yml裏面寫入相關配置
server:
port: 9411
spring:
application:
name: zipkin-server
#允許bean被重寫
main:
allow-bean-definition-overriding: true
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
#zipkin的ui界面配置
management:
metrics:
web:
server:
auto-time-requests: false
在啓動類上面加入 @EnableEurekaClient @EnableZipkinServer 註解表示開啓eureka客戶端 ,鏈路追蹤服務端
此時zipkin-serve 搭建完畢在瀏覽器訪問 http://localhost:9411 會發現如下ui界面
3 feign-client
之所以寫這個model其實也就是爲了複習一下feign組件,並且gateway網關model去請求調用feign 再由feign去轉發調用user-service model
pom依賴
<dependencies>
<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-openfeign</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<!-- 開啓監控中心-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 使用Hystrix dashboard 監控熔斷器狀態,配合上面actuator使用 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<!-- feign自帶的hystrix並不是啓動依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<!-- 引入eureka 客戶端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<!-- 被zipkin服務追蹤的啓動依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
</dependencies>
資源文件配置
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
server:
port: 8762
spring:
application:
name: feign-client
#鏈路服務的地址
zipkin:
base-url: http://localhost:9411
#被追蹤的可能性,默認是0.1 表示百分之10
sleuth:
sampler:
probability: 1.0
#開啓hystrix服務保護熔斷降級
feign:
hystrix:
enabled: true
#開啓全局監控
management:
endpoints:
web:
exposure:
include: "*"
在啓動類上加入相關的註解
在啓動類同包下新建controller services feignclient三個包
新建UserController.java文件
import com.example.userservice.services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
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;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/hi")
public String hi(@RequestParam("name") String name){
return userService.sayHi(name);
}
}
UserService.java文件
import com.example.userservice.feignclient.UserFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserFeignClient userFeignClient;
public String sayHi(String name){
return userFeignClient.sayHi(name);
}
}
UserFeignClient.java文件
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* @FeignClient 是一個請求的feign調用客戶端
* value 表示請求的相關的server_id 暴露到eureka裏面的
* path 是請求的相關路徑
* contextId 表示相關的feign client模塊
* */
@FeignClient(value ="user-service",path = "/user",contextId = "userFeignClient")
public interface UserFeignClient {
@GetMapping(value = "/hi")
String sayHi(@RequestParam("name") String name);
}
4 user-service 測試的service model
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<!-- 被zipkin服務追蹤的啓動依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!-- web應用 -->
<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>
相關配置文件
server:
port: 8763
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: user-service
sleuth:
sampler:
probability: 1.0
zipkin:
base-url: http://localhost:9411
啓動類上加入 @EnableEurekaClient 註解,在同包下新建controller包,並且新建 UserController.java,爲了方便直接輸出
import org.springframework.beans.factory.annotation.Value;
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;
@RestController
@RequestMapping("/user")
public class UserController {
@Value("${server.port}")
String port;
@GetMapping("/hi")
public String home (@RequestParam String name) {
return "hi "+name+", i am port :"+port;
}
}
此時啓動完畢之後 依次啓動eureka ,zipkin ,feign ,user-service
在瀏覽器輸入 http://localhost:8762/user/hi?name=hello world 會發現輸出
此時重新進入剛纔打開的zipkin的UI界面 點擊find Traces 會發現有服務跟蹤,自此本文已經實現了鏈路跟蹤
點擊導航欄的dependencies 會發現鏈路跟蹤的相關服務依賴
很顯然,在實際開發過程中我們會有很多很多服務,在目前前後端分離的主流情況下,前臺不會記住後端每個服務的具體請求路徑,很顯然這就需要網關來幫助我們進行請求的統一分發,並且網關不僅僅只有這點重用,還有身份驗證,過濾請求,服務器保護,服務限流,防止攻擊,黑白名單的配置 等作用,在下期博客中,會寫入使用JWT來進行身份校驗和過濾不合法請求,很顯然網關必不可少,所以進入下面 gateway網關的搭建
5 gateway-server 網關的搭建
整合demo的請求邏輯見上,現在搭建網關pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 引入eureka 客戶端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<!-- 被zipkin服務追蹤的啓動依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
配置文件
spring:
cloud:
gateway:
# gateway 運行從註冊中心發現服務
discovery:
locator:
enabled: true
#服務serviceId不分區大小寫
lowerCaseServiceId: true
routes:
#網關路由的轉發 lb:// 表示是從註冊中心發現serviceId
- id: feign-client
uri: lb://feign-client
predicates:
- Path=/feign-client/**
filters:
- StripPrefix=1
application:
name: gateway-server
sleuth:
sampler:
probability: 1.0
zipkin:
base-url: http://localhost:9411
server:
port: 5000
feign:
hystrix:
enabled: true
logging:
level:
org.springframework.cloud.gateway: debug
啓動gateway
瀏覽器上面請求 http://localhost:5000/feign-client/user/hi?name=hello world
請求結果和直接請求feign一樣 ,但是比對url會發現該請求是從網關分發的,如果你不信,覺得我再胡說,那我們去看服務跟蹤
鏈路跟蹤界面上點擊find traces 會發現剛纔請求的服務已經被跟蹤到
接着點擊跟蹤traces 會發現每一個服務處理耗時
同時點擊依賴會發現 會發現依賴關係圖
自此,本章博客結束 ,如果有不正確的,歡迎在評論區中指正
demo 源碼地址 https://github.com/xzjayx/zipkin