Spring Cloud實戰小技巧必殺技
spring cloud 實踐
項目結構
config 配置中心
埠:8888,方便起見直接讀取配置文件,生產環境可以讀取git。application-dev.properties為全局配置。先啟動配置中心,所有服務的配置(包括註冊中心的地址)均從配置中心讀取。
eureka 註冊中心
埠:8761,/metadata端點實現metadata信息配置。
zuul 網關
埠:8080,演示解析token獲得label並放入header往後傳遞
core 框架核心包
核心jar包,所有微服務均引用該包,使用AutoConfig實現免配置,模擬生產環境下spring-cloud的使用。
starter spring cloud以及core框架依賴簡化starter
provider 服務提供者
api 服務提供者SDK
強制服務消費方只能通過服務提供者提供的SDK包(api項目)進行調用,以便更加方便控制服務消費方的行為:
提供可能的優化,SDK直接讀取緩存(SDK只讀緩存,寫緩存放還是在微服務)。
統計有哪些服務消費者,info端點顯示包依賴,通過註冊中心遍歷所有服務。
方便dubbo平滑遷移,介面加feign註解。
service 服務提供者微服務
埠:18090,服務提供者,無特殊邏輯。
consumer 服務消費者
埠:18090,調用服務提供者。
Restful API 設計規範
/版本/訪問控制/域對象
/版本/訪問控制/域對象/action/動作
版本
版本為微服務級別,也就是說不存在一個API是v3版,其他API還只是v1版的問題,要升級所有API版本一起升級,但是需要保證之前版本v1-v3還可以使用。
原則上要兼容上一個版本 如果當前是 /v3 則 /v2 要求可以正常使用 /v1 不做要求
如果無法兼容 需要通知所有服務消費者 並約定版本火車 一起上線時間
小技巧
下面swagger註解就可以實現上述要求,路徑中的沒有限定,其實可以是任意內容,通過swagger文檔來進行約定
訪問控制
用於在網關統一進行訪問控制, 訪問控制分為
pb - public 所有請求均可訪問
pt - protected 需要進行token認證通過後方可訪問
df - default 網關進行token認證 並且請求參數和返回結果進行加解密
pv - private 無法通過網關訪問 只能微服務內部調用
其他 同pv
action
無法用名詞+請求方法表述的可以擴展為 /域對象/action/動詞 必須為POST方法
例如 POST /users/action/login
問題描述
主要由於使用了API(SDK)為了偷懶,以及Restful API路徑中的版本帶來的一系列問題。
spring MVC 不支持繼承介面中方法參數上的註解(支持繼承類、方法上的註解)
API中為了方便,使用feign替代RestTemplate手動調用。帶來的問題:springMVC註解想偷懶,只在feign介面寫一遍,然後實現類繼承此介面即可。 例如: feign介面定義如下
service實現類方法參數必須再寫一次@RequestBody註解,方法上的@RequestMapping註解可以省略
解決辦法,@Configuration配置類添加如下代碼,擴展spring默認的ArgumentResolvers
swagger不支持繼承介面中方法參數上的註解(支持繼承類、方法上的註解)
沒有找到swagger自帶擴展點能夠優雅擴展的方法,只好修改源碼了,下載springfox-spring-web 2.8.0 release源碼包。 添加pom.xml
添加ResolvedMethodParameterInterface繼承ResolvedMethodParameter
修改HandlerMethodResolver類line 181,將ResolvedMethodParameter替換為ResolvedMethodParameterInterface,重新打包deploy,並在swagger相關依賴中強制指定修改後的版本。
這樣就能夠順利生產swagger文檔啦。
feign不支持GET方法傳遞POJO
由於springMVC是支持GET方法直接綁定POJO的,只是feign實現並未覆蓋所有springMVC特效,網上的很多變通方法都不是很好,要麼是吧POJO拆散成一個一個單獨的屬性放在方法參數里,要麼是把方法參數變成Map,要麼就是要違反HTTP協議,GET傳遞@RequestBody:
https://www.jianshu.com/p/7ce46c0ebe9d
https://github.com/spring-cloud/spring-cloud-netflix/issues/1253
解決辦法,使用feign攔截器:
feign不支持路徑中的
對於一個典型的Restful API定義如下:
我們並不關心路徑中的,因此方法參數中也沒有@PathVariable("version"),這個時候feign就傻了,不知道路徑中的應該被替換成什麼值。 解決辦法 使用自己的Contract替換SpringMvcContract,先將SpringMvcContract代碼複製過來,修改其中processAnnotationOnMethod方法的代碼,從swagger註解中獲得的值:
然後在自己的AutoConfig中聲明成spring的bean
spring cloud以及feign小技巧
要求源碼對dev環境負責(application.properties里的配置均為dev環境地址)
配置中心dev環境全局配置添加:
在開發過程中,dev環境會部署一套微服務到伺服器上,本機開發時為了不影響dev伺服器,spring.application.name添加自己姓名為前綴,註冊到dev註冊中心也不影響dev伺服器,配置中心指定名字,不再隨spring.application.name變化。 啟動參數添加:
bootstrap.properties配置模板
這樣本機開發可以調用伺服器上的微服務,但是伺服器上的微服務不會調用本機(服務名修改了)。
那麼如果兩名研發需要互相調用聯調該如何處理呢?
@FeignClient註解不要寫死服務名,使用place holder,類似如下代碼:
ProviderApiAutoConfig的代碼如下:
這樣在啟動參數中指定哪個服務想調哪個人的實例都可以。同時處理了service依賴api時,不會注入feign的api實例。
TAG:SpringCloud社區 |