背景
目前公司還存在諸多前後端未分離專案(後面簡稱FM
專案),開發同學在本地只能聯調alpha
環境,但是在專案轉測轉演之後,測試同學提的jira
單都是hwbeta
、gamma
環境的,因此開發同學為了復現問題場景需要在alpha
環境造單,或者麻煩測試同學造單,此過程非常低效,希望能夠在本地聯調hwbeta
、gamma
環境的服務,本文著力解決此問題。
分析
我們以本地啟動webagent
閘道器服務聯調本地agentBuy-service
服務為例分析流程。
agentBuy-service
服務是一個controller
層服務,呼叫其他遠端服務獲取資料並注入到頁面檔案(ftl
)中,然後使用freemarker
引擎將ftl
編譯成html
並返回給瀏覽器。預設呼叫alpha
環境的遠端服務,如果想呼叫hwbeta
、gamma
環境的遠端服務,首先需要搞清楚遠端服務呼叫的流程。
遠端服務呼叫過程
現在我們深度分析下遠端服務呼叫過程,先來了解agentBuy-service
服務如何整合Euraka
、Feign
、Ribbon
實現遠端服務請求、服務註冊與發現、負載均衡的。首先了解下Eureka
,其官方結構圖如下:
Spring-Cloud Euraka
是Spring Cloud
集合中一個元件,它是對Euraka
的整合,用於服務註冊和發現。Eureka
是Netflix
中的一個開源框架。它和 zookeeper
、Consul
一樣,都是用於服務註冊管理的,同樣,Spring-Cloud
還整合了Zookeeper
和Consul
。
Eureka
由多個instance
(服務例項)組成,這些服務例項可以分為兩種:Eureka Server
和Eureka Client
。為了便於理解,我們將Eureka client
再分為Service Provider
和Service Consumer
。
Eureka Server
為服務註冊中心,向外暴露自己的地址,負責管理、記錄服務提供者的資訊,同時將符合要求的服務提供者地址列表返回服務消費者Service Provider
為服務提供者,在服務啟動後,服務提供者向Eureka
註冊自己的IP
、埠、提供服務等資訊,並定時續約更新自己的狀態等Service Consumer
為服務消費者,通過Eureka Server
發現得到所需服務的提供者地址資訊,然後向服務提供者發起遠端呼叫
agentBuy-service
是一個繼承了Spring MVC
的Maven Web
專案,一個controller
層服務,不需要向其他服務提供服務,因此不需要將自己註冊到Eureka Server
,只需要將其配置成Service Consumer
(1)在pom
檔案中新增Eureka-client
依賴
<dependency>
<groupId>com.netflix.eureka</groupId>
<artifactId>eureka-client</artifactId>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
(2)在eureka-client.properties
配置檔案中增加相關配置資訊,設定不需要註冊到Eureka Server
,新增eureka.registration.enabled=false
和eureka.registerWithEureka=false
,詳細配置如下:
// eureka-client.properties
###Eureka Client configuration for Sample Eureka Client
# see the README in eureka-examples to see an overview of the example set up
# note that for a purely client usage (e.g. only used to get information about other services,
# there is no need for registration. This property applies to the singleton DiscoveryClient so
# if you run a server that is both a service provider and also a service consumer,
# then don't set this property to false.
eureka.registration.enabled=false # 表示是否註冊到Eureka Server,預設為true
## configuration related to reaching the eureka servers
eureka.preferSameZone=true
eureka.shouldUseDns=false
eureka.registerWithEureka=false # 表示是否將自己註冊到Eureka Server,預設為true
eureka.serviceUrl.default=http://10.118.71.204:8761/eureka/ # 註冊中心地址
eureka.appinfo.replicate.interval=10
eureka.vipAddress=agentbuy-service # 定義服務名變數
eureka.name=${eureka.vipAddress} # 服務名,SpringCloud中服務呼叫的依據
eureka.port=8001 # 服務埠
#eureka.ipAddr=192.168.29.170
#eureka.instanceId=${eureka.vipAddress}:${eureka.port}
#eureka.hostname=${eureka.ipAddr}
eureka.homePageUrlPath=/${eureka.vipAddress}
#eureka.statusPageUrlPath=/${eureka.vipAddress}/status
#eureka.healthCheckUrlPath=/${eureka.vipAddress}/health
eureka.lease.renewalInterval=5
eureka.lease.duration=15
eureka.decoderName=JacksonJson
另外,agentBuy-service
整合Ribbon
實現客戶端負載均衡,Spring Cloud Ribbon
是一個基於HTTP
和TCP
的客戶端負載均衡工具,可以讓我們輕鬆地將面向服務的REST
模版請求自動轉換成客戶端負載均衡的服務呼叫
還整合Feign
實現依賴服務介面的定義。在Spring Cloud feign
的實現下,只需要建立一個介面並用註解方式配置它,即可完成服務提供方的介面繫結,簡化了在使用Spring Cloud Ribbon
時自行封裝服務呼叫客戶端的開發量。也就是說Feign
封裝好了與其他服務的請求、響應處理等;
以訂單服務遠端呼叫庫存服務為例,描述Eureka
、Ribbon
、Feign
三者之間的協同關係:
參考:一文讀懂SpringCloud與Eureka,Feign,Ribbon,Hystrix,Zuul核心元件間的關係
agentBuy-service
遠端呼叫inquiry-service
在釋出詢價頁面會呼叫agentBuy-service
服務中/getdeliveryaddresses/{companyId}/user/{userLoginId}
介面獲取使用者收穫地址,介面controller
層遠端呼叫了inquiry-service
服務的findReceiveAddresses
方法獲取使用者收穫地址
使用構造器建立
Bean
例項,constructor-arg
子元素配置一個構造器引數,給FeignClientBuilder
類的configAgentUrl
屬性(遠端服務地址)賦值,其中api.intra.url
在application.properties
配置檔案中定義api.intra.url=http://alpha-api.intra.casstime.com
上面採用FeignClientBuilder
動態建立FeignClient
例項去發起遠端呼叫,而不是使用@Autowired
註解讓 spring
完成 bean
自動裝配的工作
@FeignClient(name = "inquiry-service")
public interface InquiryClient extends InquiryService{
}
然後向Spring
容器中,注入FeignClient
例項:
@Autowired private InquiryClient inquiryClient;
這是因為Spi
包中提供的feign
介面,是依賴於Spring Boot
的,因此要求外部系統必須是Spring Boot
應用,同時由於feign
介面配置中沒有指定服務呼叫的url
地址,而採用指定服務名的方式,導致外部系統如果想呼叫feign
介面,必須要和使用者許可權服務註冊在同一個註冊中心上。
agentBuy-service
不是Spring Boot
服務,採用FeignClientBuilder
動態建立FeignClient
例項可以擺脫對Spring Boot
的依賴。
agentBuy-service
服務本地聯調其他環境
上面說到agentBuy-service
是一個maven web
服務,如果需要在本地聯調hwbeta、gamma
環境,只需要將遠端呼叫服務地址指向hwbeta、gamma
環境
(1)通過閘道器webagent
走本地agentBuy-service
(2)更改agentBuy-service
遠端服務呼叫地址
因為agentBuy-service
採用FeignClientBuilder
動態建立FeignClient
例項去發起遠端呼叫,通過指定FeignClientBuilder
中configAgentUrl
可以跨Eureka
呼叫服務,不需要通過Eureka Server
定位服務