sb2.0新版springcloud微服務實戰:Consul+Zuul+Feign/Ribbon+Hystrix Turbine+Config+sleuth+zipkin
sb2.0新版springcloud微服務實戰:Eureka+Zuul+Feign/Ribbon+Hystrix Turbine+SpringConfig+sleuth+zipkin
springboot 版本是 2.0.3.RELEASE ,springcloud 版本是 Finchley.RELEASE
本篇文章是springboot2.x升級後的升級springcloud專貼,因為之前版本更新已經好久了,好多人評論可不可以出個新版本,大家一定要注意,這是springboot2.x版本的,springboot1.x的請參考 點選檢視文章,基本元件都不變就是升級jar包版本,主要就是hystrix-dashboard使用有點變化。
相信現在已經有很多小夥伴已經或者準備使用springcloud微服務了,接下來為大家搭建一個微服務框架,後期可以自己進行擴充套件。會提供一個小案例: 服務提供者和服務消費者 ,消費者會呼叫提供者的服務,新建的專案都是用springboot,附原始碼下載,推薦使用coding地址下載,因為可以切換分支,後期可以及時更新。
coding倉庫地址(推薦下載): coding地址 遠端配置倉庫地址 遠端配置倉庫地址
如果有問題請在下邊評論,或者200909980加群交流。或者關注文章結尾微信公眾號,私信後臺
Eureka/Consul/Zookeeper:服務發現 (根據情況選擇一個,eureka已經宣佈閉源)
Hystrix:斷路器
Zuul:智慧路由
Ribbon/Feign:客戶端負載均衡 (Feign用的更多)
Turbine&hystrix-dashboard:叢集監控
Springcloud-config:遠端獲取配置檔案
接下來,我們開始搭建專案,首先我們到spring為我們提供的一個網站快速搭建springboot專案,點選訪問,我這裡用的是gradle,如果各位客官喜歡用maven,好吧你可以到http://mvnrepository.com/檢視對應的依賴,點我訪問。
一、搭建consul服務
使用 eureka 作為服務發現 請參考點選檢視使用eureka作為服務註冊中心
springclound-consul作為服務發現的核心,第一個搭建,後面的服務都要註冊到consul上,意思是告訴consul自己的服務地址是啥。當然還可以用zookeeper或者eureka。
- 1下載安裝consul
consul的下載地址consul下載地址,根據自己電腦系統下載對應的包。
我這裡是windows64,網上說要配置環境變數,就可以直接使用,但是我這裡不行。具體方法是,下載解壓後是一個.exe可執行檔案,然後配置當前路勁到path中,然後直接在cmd命令視窗中,輸入consul agent -dev 就可以啟動了,如果不行的話,就在cmd命令視窗進如到consul的下載目錄,然後執行上面的命令。然後consul的預設埠是8500,直接在瀏覽器開啟http://localhost:8500,就可以看到控制檯了
二、搭建config-server服務sc-config-server
springcloud-config-server是用來將遠端git倉庫的配置檔案動態拉下來,這樣配置檔案就可以動態的維護了。當然也可以選擇本地倉庫。
新建一個springboot專案,修改maven私服地址,並加入一下依賴。
- 1.修改build.gradle檔案
compile('org.springframework.cloud:spring-cloud-config-server')
compile('org.springframework.cloud:spring-cloud-starter-consul-discovery')
//連線config-server也需要使用者名稱和密碼
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.boot:spring-boot-starter-actuator')
- 2.修改application.yml檔案
server:
port: 8800
spring:
security:
basic:
enabled: true
user:
name: root
password: booszy
application:
name: sc-config-server
cloud:
config:
server:
git:
uri: https://git.coding.net/yirenyishi/springcloud-config-profile
searchPaths: '{application}'
consul:
host: localhost
port: 8500
discovery:
instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
ip-address: true
- 3.修改啟動類
修改啟動類,要加入這三個註解,因為要註冊到consul上,所以需要@EnableDiscoveryClient這個註解
@EnableConfigServer
@EnableDiscoveryClient
@SpringBootApplication
public class Sb2scConfigApplication {
public static void main(String[] args) {
SpringApplication.run(Sb2scConfigApplication.class, args);
}
}
然後執行啟動springboot專案,等啟動成功後訪問consul的頁面,會發現sc-config-server已經註冊到上面了,如果啟動報錯,請檢查錯誤資訊。
三、搭建服務提供者服務sc-provider
編寫一個服務提供者,為下邊的消費者提供服務,用到了spring-webflux(spring新出的非阻塞式框架)不是springmvc,當然你們公司用什麼你還是繼續用什麼。
- 注意 : 這裡除了application.xml,還需要一個bootstrap.yml, 因為bootstrap.yml得載入順序是在application.xml前邊,服務註冊和config配置必須放到bootstrap.yml。
- 修改build.gradle檔案
compile('org.springframework.cloud:spring-cloud-starter-consul-discovery')
compile('org.springframework.cloud:spring-cloud-starter-config')
compile('org.springframework.boot:spring-boot-starter-webflux')
compile('org.springframework.boot:spring-boot-starter-actuator')
- 2.編寫配置檔案bootstrap.yml
** 注意 : 這裡除了application.xml,還需要一個bootstrap.yml*
application.xml我是放到遠端倉庫地址的,大家可以直接到我的遠端倉庫,根據專案名(sc-provider-config)查詢。配置檔案的倉庫地址:點選訪問。
spring:
application:
name: sc-provider
cloud:
consul:
host: localhost
port: 8500
discovery:
instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
ip-address: true
config:
discovery:
enabled: true
service-id: sc-config-server
fail-fast: true
username: root
password: booszy
profile: csdn
- 3.編寫程式碼
編寫主類
@EnableDiscoveryClient
@SpringBootApplication
public class Sb2scProviderApplication {
public static void main(String[] args) {
SpringApplication.run(Sb2scProviderApplication.class, args);
}
}
新建IndexController進行測試,這裡只是為了測試,案例程式碼使用的是webflux,如果想使用springmvc,修改jar包依賴即可。
@RestController
@RequestMapping("test")
public class IndexController {
//返回一個實體
@GetMapping("{msg}")
public Mono<String> sayHelloWorld(@PathVariable("msg") String msg) {
System.out.println("come on " + msg);
return Mono.just("sc-provider receive : " +msg);
}
//返回一個列表
@GetMapping("list")
public Flux<Integer> list() {
List<Integer> list = new ArrayList<>();
list.add(8);
list.add(22);
list.add(75);
list.add(93);
Flux<Integer> userFlux = Flux.fromIterable(list);
return userFlux;
}
}
執行springboot專案,去consul檢視,有沒有註冊上。
我們的sc-provider已經註冊到eureka上了,訪問介面,成功。
四、搭建消費者服務sc-consumer
消費者要訪問服務提供者的服務,這裡用的是通過RestTemplate/feign請求resetful介面,使用ribbon做客戶端負載均衡,hystrix做錯誤處理,feign和ribbon二選一,案例中ribbon和feign都有,也可以都用。
還是熟悉的配方,熟悉的味道,新建springboot專案,新增專案依賴。
- 1.修改build.gradle檔案
compile('org.springframework.cloud:spring-cloud-starter-consul-discovery')
compile('org.springframework.cloud:spring-cloud-starter-config')
compile('org.springframework.boot:spring-boot-starter-webflux')
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.cloud:spring-cloud-starter-openfeign')
compile('org.springframework.cloud:spring-cloud-starter-netflix-hystrix')
- 2.修改bootstrap.yml檔案
application.yml 在git倉庫,請前往git倉庫檢視。
spring:
application:
name: sc-consumer
cloud:
consul:
host: localhost
port: 8500
discovery:
instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
ip-address: true
config:
discovery:
enabled: true
service-id: sc-config-server
fail-fast: true
username: root
password: booszy
profile: csdn
#新版配置,否則後面dashboard無法找到hystrix.stream
management:
endpoints:
web:
exposure:
include: '*'
- 3.編寫程式碼
啟動類程式碼
@RibbonClient 指定服務使用的負載均衡型別,name不指定服務則為所有的服務開啟負載均衡,也可以在用yml中進行配置。
@EnableHystrix 是支援hystrix開啟斷路器,在規定時間內失敗引數超過一定引數,就會開啟斷路器,不會發起請求,而是直接進入到錯誤處理方法。
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker
@EnableHystrix
@SpringBootApplication
public class Sb2scConsumerApplication {
// ribbon需要配置,負載均衡
@Autowired
private RestTemplateBuilder builder;
// ribbon需要配置,負載均衡
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return builder.build();
}
public static void main(String[] args) {
SpringApplication.run(Sb2scConsumerApplication.class, args);
}
}
1.ribbon案例
ribbon不需要單獨依賴,新建 RibbonController
ribbon一個坑,不能接受List型別,要使用陣列接收。
@HystrixCommand(fallbackMethod="fallbackMethod")
如果請求失敗,會進入fallbackMethod這個方法,fallbackMethod這個方法要求引數和返回值與回撥他的方法保持一致。
@RestController
public class RibbonController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/ribbon/{wd}")
@HystrixCommand(fallbackMethod="fallbackMethod")
public Mono<String> sayHelloWorld(@PathVariable("wd") String parm) {
String res = this.restTemplate.getForObject("http://sc-provider/test/" + parm, String.class);
return Mono.just(res);
}
public Mono<String> fallbackMethod(@PathVariable("wd") String parm) {
return Mono.just("fallback");
}
執行springboot專案,先看有沒有註冊到consul上。
註冊成功後,訪問介面,測試是否正確。
ribbon使用就是這麼簡單,ribbon是springboot自帶,所以不需要單獨新增依賴。
2.feign案例
在實際開發中,feign使用的還是挺多的,feign底層還是使用了ribbon。廢話不多說,直接上步驟,在服務消費者中使用feign訪問服務提供者。
- 1配置檔案
ribbon:
ReadTimeout: 30000
ConnectTimeout: 15000
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 10000
feign的預設請求超時時間是1s,所以經常會出現超時的問題,這裡我設定的是10s。ribbon的請求時間也要設定,因為feign用的是ribbon。這裡貼的是application.yml檔案中的一小段
- 2 編碼
1、主類註解
@EnableFeignClients
@EnableCircuitBreaker
@EnableHystrix
這三個都要,hystrix主要作用是斷路器,會進如fein的fallback中。 主類程式碼在上面已經貼出來了
2、編寫feign介面,MFeignClient.class
name是指要請求的服務名稱。這裡請求的是服務提供者
fallback 是指請求失敗,進入斷路器的類,和使用ribbon是一樣的。
configuration 是feign的一些配置,例如編碼器等。
@FeignClient(name = "sc-provider",fallback = MFeignClientFallback.class, configuration = MFeignConfig.class)
public interface MFeignClient {
// 這是被請求微服務的地址,也就是provider的地址
@GetMapping(value = "/test/{msg}")
String sayHelloWorld(@PathVariable("msg") String msg);
@GetMapping(value = "/test/list")
List<Integer> list();
@GetMapping(value = "/test/list")
Integer[] array();
}
- 3 MFeignConfig.class feign的配置
這裡配置了feign的列印日誌等級
@Configuration
public class MFeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
- 4 MFeignClientFallback.class ,斷路器回撥方法
斷路器要實現上邊定義的MFeignClient介面,請求失敗,進入斷路器時,會回撥這裡的方法。
@Component
public class MFeignClientFallback implements MFeignClient{
@Override
public String sayHelloWorld(String msg) {
return "fallback";
}
@Override
public List<Integer> list() {
return new ArrayList<>();
}
@Override
public Integer[] array() {
return new Integer[0];
}
}
- 5 在controller中使用feign
@RestController
public class FeignController {
@Autowired
private MFeignClient feignClient;
@GetMapping("/feign/{wd}")
public Mono<String> sayHelloWorld(@PathVariable("wd") String parm) {
String result = feignClient.sayHelloWorld(parm);
return Mono.just(result);
}
@GetMapping("/feign/list")
public Flux<Integer> list() {
List<Integer> list = feignClient.list();
Flux<Integer> userFlux = Flux.fromIterable(list);
return userFlux;
}
@GetMapping("/feign/array")
public Flux<Integer> array() {
Integer[] arrays = feignClient.array();
Flux<Integer> userFlux = Flux.fromArray(arrays);
return userFlux;
}
}
五、用zuul做路由轉發和負載均衡
這些微服務都是隱藏在後端的,使用者是看不到,或者不是直接接觸,可以用nginx或者zuul進行路由轉發和負載均衡,zuul負載均衡預設用的是ribbon。
- 1.修改build.gradle檔案
compile('org.springframework.cloud:spring-cloud-starter-consul-discovery')
compile('org.springframework.cloud:spring-cloud-starter-config')
compile('org.springframework.cloud:spring-cloud-starter-netflix-zuul')
compile('org.springframework.boot:spring-boot-starter-actuator')
- 2.修改bootstrap.yml
還是原來的配方,application.yml在git倉庫
spring:
application:
name: sc-zuul
cloud:
consul:
host: localhost
port: 8500
discovery:
instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
ip-address: true
config:
discovery:
enabled: true
service-id: sc-config-server
fail-fast: true
username: root
password: booszy
profile: csdn
- 3.啟動類
@RefreshScope這個註解是當application.yml配置檔案發生變化的時候,不需要手動的進行重啟,呼叫localhost:8400/refresh,就會載入新的配置檔案,當然正在訪問的客戶並不影響還是使用舊的配置檔案,因為不是重啟,後來的使用者會使用新的配置檔案。注意這塊的重新整理要用post請求。
@EnableDiscoveryClient
@SpringBootApplication
@EnableZuulProxy
@RefreshScope
public class Sb2scZuulApplication {
public static void main(String[] args) {
SpringApplication.run(Sb2scZuulApplication.class, args);
}
}
啟動springboot專案,訪問consul
這時候,我們就要通過zuul訪問微服務了,而不是直接去訪問微服務。
應該訪問地址http://localhost:8400/sc-consumer/feign/list,這塊你要換成你的zuul地址。
但是有些人就會說,這樣以後使用者請求會不會太長,比較反感,所以可以通過配置進行修改訪問地址。
zuul:
routes:
springcloud-consumer-config: /consumer/**
springcloud-provider-config: /provider/**
在application.yml中加入這樣一段配置,其實就是nginx中的反向代理,使用一下簡短的可以代理這個微服務。這個時候我們就可以這樣去訪問了http://localhost:8400/consumer/feign/list,是不是簡短了很多
六、用hystrix-turbine-dashboard 做叢集監控
專案在生產環境中,每個服務的訪問量都不通,有些服務的訪問量比較大,有時候有些服務掛了,不能繼續服務,需要重啟的時候,我們並不知道,所以這時候就需要使用hystrix-turbine-dashboard做一個監控,監控所有的微服務,可以看到這個介面實時訪問量,和健康狀況。
新建一個springboot專案,老套路,加入如下依賴
- 1 新增依賴
compile('org.springframework.cloud:spring-cloud-starter-consul-discovery')
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.cloud:spring-cloud-starter-netflix-hystrix')
compile('org.springframework.cloud:spring-cloud-starter-netflix-hystrix-dashboard')
compile('org.springframework.cloud:spring-cloud-starter-netflix-turbine')
如果啟動的時候報錯要排除一下eureka依賴
configurations {
compile.exclude module: 'eureka-client'
}
- 2 修改application.yml配置檔案
注意:是application.yml,這裡不需要bootstrap.yml
server:
port: 8900
turbine:
aggregator:
clusterConfig: default
appConfig: sc-consumer
clusterNameExpression: "'default'"
spring:
application:
name: sc-dashboard
cloud:
consul:
host: localhost
port: 8500
discovery:
instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
ip-address: true
appConfig 後面是要檢測的註冊在consul上的服務名,必須要有
如果啟動報錯,找不到hystrix.stream,在你要監控的微服務加入如下配置。
management:
endpoints:
web:
exposure:
include: '*'
- 3 修改主類
@EnableTurbine ,@EnableHystrixDashboard 一個都不能少
@EnableDiscoveryClient
@SpringBootApplication
@EnableTurbine
@EnableHystrixDashboard
public class Sb2scDashboardApplication {
public static void main(String[] args) {
SpringApplication.run(Sb2scDashboardApplication.class, args);
}
}
- 4 訪問測試
這塊的埠是8900,訪問地址http://localhost:8900/hystrix,看到的是下面的頁面。
然後在那個網址的輸入框裡輸網址http://localhost:8900/turbine.stream,點選monitor stream。剛開啟的時候可能是空的,什麼也沒有,這並不表示你已經錯了。這時候你訪問消費者服務的介面,例如訪問http://localhost:8400/consumer/feign/list,多訪問幾次,然後看控制檯有沒有出現一個監控皮膚,沒有就等會重新整理一次,如果一直不出現,應該是配置有問題。
七、使用sleuth+zipkin 實現鏈路追蹤服務
在使用微服務的時候,我們發現,有時候排錯不好排查,所以就給大家整個這個鏈路追蹤,很方便知道是哪一個服務呼叫哪一個服務出現了問題。因為有些專案可能服務比較多。
- 1 新增依賴
新建一個springboot專案
雖然其他服務呼叫zipkin不是從eureka上動態過去服務地址,而是硬編碼,但是這塊還是考慮吧zipkin註冊到eureka上。
compile('org.springframework.cloud:spring-cloud-starter-consul-discovery')
compile group: 'io.zipkin.java', name: 'zipkin-server', version: '2.9.3'
compile group: 'io.zipkin.java', name: 'zipkin-autoconfigure-ui', version: '2.9.3'
compile('org.springframework.boot:spring-boot-starter-actuator')
如果提示log4j有衝突,要排除依賴
configurations {
compile.exclude module: 'log4j'
compile.exclude module: 'slf4j-log4j12'
compile.exclude module: 'spring-boot-starter-logging'
}
- 2 修改application配置檔案
server:
port: 9411
spring:
application:
name: sc-sc-zipkin
profiles:
active: csdn
cloud:
consul:
host: localhost
port: 8500
discovery:
instance-id: ${spring.application.name}:${spring.cloud.client.ipAddress}:${spring.application.instance_id:${server.port}}
ip-address: true
management:
metrics:
web:
server:
auto-time-requests: false
- 3 主類註解新增
@EnableZipkinServer 主要是這個註解
啟動服務後訪問http://localhost:9411,就可以開啟zipkin的控制檯頁面,這時候應該是什麼都沒有
@EnableDiscoveryClient
@SpringBootApplication
@EnableZipkinServer
public class Sb2scZipkinApplication {
public static void main(String[] args) {
SpringApplication.run(Sb2scZipkinApplication.class, args);
}
}
- 4 其他服務中呼叫
這裡我們在消費者服務和提供者服務裡都加入如下依賴
compile('org.springframework.cloud:spring-cloud-starter-sleuth')
compile('org.springframework.cloud:spring-cloud-starter-zipkin')
然後修改配置檔案,bootstrap.yml、
這塊zipkin的地址是硬編碼的,目前還沒發現怎麼從服務註冊中心eureka上動態獲取,以後有解決方案,會更新帖子
sleuth這個是配置提取率,可以配置也可以不配置
spring:
zipkin:
base-url: http://localhost:9411
sleuth:
sampler:
percentage: 1.0
啟動服務,然後訪問消費者服務的介面,這時候訪問zipkin的控制檯http://localhost:9411
點選依賴分析,可以看到呼叫服務鏈,因為這塊只涉及到兩個服務,所以只有兩個,在實際生產環境中,這塊可能有很多,到時候看起來就特別直觀了。
關注
如果有問題,請在下方評論,或者加群討論 200909980
關注下方微信公眾號,可以及時獲取到各種技術的乾貨哦,如果你有想推薦的帖子,也可以聯絡我們的。
相關文章
- SpringCloud微服務架構開發實戰SpringGCCloud微服務架構
- springcloud微服務實戰 學習筆記二 服務提供者SpringGCCloud微服務筆記
- springcloud微服務實戰 學習筆記三 服務消費者SpringGCCloud微服務筆記
- springcloud微服務實戰 學習筆記六 服務閘道器SpringGCCloud微服務筆記
- SpingCloud Alibaba實戰(1:微服務與SpringCloud Alibaba)GCCloud微服務Spring
- SpringCloud Alibaba實戰(7:nacos註冊中心管理微服務)SpringGCCloud微服務
- 微服務實戰系列(四)-註冊中心springcloud alibaba nacos微服務SpringGCCloud
- SpringCloud實戰 | 第五篇:SpringCloud整合OpenFeign實現微服務之間的呼叫SpringGCCloud微服務
- 【轉】微服務實戰微服務
- 微服務實戰SpringCloud之Spring Cloud Feign替代HTTP Client微服務SpringGCCloudHTTPclient
- SpringCloud Gateway微服務閘道器實戰與原始碼分析-上SpringGCCloudGateway微服務原始碼
- springcloud微服務實戰 學習筆記四 分散式配置中心SpringGCCloud微服務筆記分散式
- SpringCloud微服務專案實戰 - API閘道器Gateway詳解實現SpringGCCloud微服務APIGateway
- SpringCloud 微服務最佳開發實踐SpringGCCloud微服務
- SpringCloud微服務治理SpringGCCloud微服務
- springcloud 微服務面試SpringGCCloud微服務面試
- 本地服務呼叫K8S環境中的SpringCloud微服務實戰K8SSpringGCCloud微服務
- SpringCloud微服務實戰——搭建企業級開發框架(九):使用Nacos發現、配置和管理微服務SpringGCCloud微服務框架
- SpringCloud微服務實戰——搭建企業級開發框架(十一):整合OpenFeign用於微服務間呼叫SpringGCCloud微服務框架
- 微服務實戰(八)整合Sentinel閘道器服務限流功能 SpringCloud GateWay + Sentinel + Nacos微服務SpringGCCloudGateway
- SpringCloud微服務實戰——搭建企業級開發框架(三十七):微服務日誌系統設計與實現SpringGCCloud微服務框架
- SpringCloud微服務實戰——搭建企業級開發框架(三十四):SpringCloud + Docker + k8s實現微服務叢集打包部署-Maven打包配置SpringGCCloud微服務框架DockerK8SMaven
- SpringCloud微服務實戰——搭建企業級開發框架(十九):Gateway使用knife4j聚合微服務文件SpringGCCloud微服務框架Gateway
- SpringCloud微服務基礎SpringGCCloud微服務
- SpringCloud微服務理解(一)SpringGCCloud微服務
- SpringCloud微服務整合DubboSpringGCCloud微服務
- 微服務實戰系列(三)-springcloud、springboot及maven之間關係微服務GCCloudSpring BootMaven
- SpringCloud微服務實戰——搭建企業級開發框架(三十五):SpringCloud + Docker + k8s實現微服務叢集打包部署-叢集環境部署SpringGCCloud微服務框架DockerK8S
- SpringCloud(1) ——回顧微服務和微服務架構SpringGCCloud微服務架構
- spring cloud 微服務實戰SpringCloud微服務
- Golang 微服務優化實戰Golang微服務優化
- springcloud 微服務 之 Eureka 配置SpringGCCloud微服務
- 微服務之springcloud eureka(一)微服務SpringGCCloud
- 微服務實戰(一):微服務架構的優勢與不足微服務架構
- spring微服務實戰(二):使用Spring Boot建立微服務微服務Spring Boot
- .Net微服務實戰之CI/CD微服務
- Go+MongoDB的微服務實戰MongoDB微服務
- 微服務實戰(二):使用API Gateway微服務APIGateway