摘自:螞蟻課堂:http://www.mayikt.com/course/video/2414
1、微服務網關平臺設計思想及作用
1、接口產生背景:在面向服務架構和微服務背景和rpc遠程調用下產生,目的是爲了解耦。
2、接口分類:
(1)開放接口:其他機構合作伙伴進行調用(必須在外網訪問)需要通過appid+appsecret生成accesstoken進行通訊, 對接支付開發,微信開發。
目的:可以授權一些接口權限oauth2.0協議方式,第三方聯合登陸。
(2)內部接口:一般只能在局域網中進行訪問,經過網關進行轉發請求,服務與服務調用之間關係都在同一個微服務系統中。
目的:保證安全問題。
3、接口設計考慮:接口權限(開放/內部)接口、冪等性、安全性(https)、防止篡改數據(驗證簽名)、使用網關攔截接口實現黑名單和白名單、接口使用http+json格式跨平臺操作(http底層使用的是socket技術,轉化成2進制)、考慮高併發(對接口服務實現保護 服務降級、熔斷、隔離之類),最後使用統一的api管理平臺api swagger
4、網關:客戶端請求統一要先請求到網關服務器上,再由網關服務器進行轉發到實際服務器上,類似於nginx。
作用:可以攔截客戶端所有請求,對該請求進行權限控制、負載均衡、日誌管理、統一異常處理、xxs、sql注入、黑名單和白名單,性能監控、日誌打印、接口調用監控等。
2、網關與過濾器區別
過濾器是攔截單個tomcat服務器請求,網關是攔截整個微服務所有請求。
3、Nginx和Zuul區別
相同點:Zuul和Nginx都可以實現負載均衡、反向代理(隱藏真實ip地址),過濾請求,實現網關的效果。
不同點:
(1)Nginx採用c語言編寫 , Zuul採用ava語言編寫。
(2)Zuul負載均衡實現:採用ribbon+eureka實現本地負載均衡 ; Nginx負載均衡實現:採用服務器實現負載均衡 .
(3)Nginx相比zuul功能會更加強大,因爲Nginx整合一些腳本語言(Nginx+lua)。
(4)Nginx適合於服務器端負載均衡 ,Zuul適合微服務中實現網關。
建議nginx + zuul實現網關,這時nginx用於實現反向代理,zuul對微服務實現網關攔截。
常用網關框架:
(1)Kong kong是基於nginx+lua進行二次開發的方案,https://konghq.com
(2)Netflix Zuul是springcloud的一個推薦組件,https://github.com/Netflix/zuul
(3)orange 是國人開發的開源程序,http://orange.sumory.com/
4、搭建SpringCloud Zuul網關平臺(基於 Eureka)
1、啓動Eureka註冊中心服務
2、建立springcloud zuul網關平臺
建立maven工程,引入依賴:
<!-- springcloud整合zuul網關 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<!-- springcloud eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
配置yml文件信息
##服務端口
server.port=6089
##註冊地址
eureka.client.serviceUrl.defaultZone=http://localhost:8100/eureka
##服務名稱
spring.application.name=service-zuul
##定義轉發服務規則
##客戶端發送請求時以app-member開頭,都會轉發到app-member服務上去
zuul.routes.service1.path=/app-member/**
##服務別名 zuul網關默認整合ribbon,自動實現負載均衡輪訓效果
zuul.routes.service1.service-id=app-member
##客戶端發送請求時以app-order開頭,都會轉發到app-order服務上去
zuul.routes.service2.path=/app-order/**
zuul.routes.service2.service-id=app-order
##默認服務讀取eureka註冊服務列表,默認讀取時間是間隔30秒
##開啓所有斷點的監控
management.endpoints.web.exposure.include=*
建立啓動類,引入@EnableZuulProxy 開啓網關代理
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class AppGateway {
//@EnableZuulProxy 開啓網關代理
public static void main(String[] args) {
SpringApplication.run(AppGateway.class, args);
}
啓動app-member服務後,通過訪問zuul配置的端口和服務名稱,即可訪問到app-member服務而不向外暴露app-member服務的地址和端口。如:app-member服務的訪問地址是:127.0.0.1:8888/app-member,通過zuul訪問就是127.0.0.1:6089/app-member。
5、Zuul網關攔截參數信息
zuul網關服務中建立過濾器用於攔截請求參數,filter須繼承ZuulFilter類並實現幾個方法,如下:
@Component
public class TokenFilter extends ZuulFilter{
/**
* 編寫過濾器攔截業務邏輯代碼
*/
@Override
public Object run() throws ZuulException {
//案例:攔截所有的服務接口,判斷服務接口上是否有傳遞usertoken參數
//獲取上下文
RequestContext currentContext = RequestContext.getCurrentContext();
//獲取request
HttpServletRequest request = currentContext.getRequest();
//獲取token時,從請求頭獲取
String token = request.getParameter("userToken");
if (StringUtils.isEmpty(token)) {
//不會繼續執行,不去調用服務接口,網關服務直接響應給客戶端
currentContext.setSendZuulResponse(false);
currentContext.setResponseBody("usertoken is null");
currentContext.setResponseStatusCode(401);
return null;
}
//不爲空的話,執行其他業務代碼
return null;
}
/**
* 判斷過濾器是否生效
*/
@Override
public boolean shouldFilter() {
// TODO Auto-generated method stub
return true;
}
/**
* 過濾器執行順序,當一個請求在同一階段的時候存在多個過濾器的時候,多個過濾器執行順序
*/
@Override
public int filterOrder() {
// TODO Auto-generated method stub
return 0;
}
/**
* 過濾器類型pre,表示在請求之前進行執行
*/
@Override
public String filterType() {
return "pre";
}
此處是驗證用戶請求須傳入token,請求經過網關時,如果不傳入token,則會返回相對應的錯誤提示,傳入token,纔會進入正常的業務服務器執行業務。
Zuul是默認集成了ribbon並開啓負載均衡,通過服務名稱訪問服務的時候,網關會在本地實現轉發,從而實現負載均衡。
6、搭建動態Zuul網關路由轉發(SpringCloud Config分佈式配置中心)
(1)在Git(碼雲)平臺建立一個yml文件,裏面加入相關配置
(2)網關整合分佈式配置中心,pom中添加依賴,yml添加配置:如下:
<!-- springcloud整合config-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
<!-- 監控中心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
##服務端口
server.port=6089
##註冊地址
eureka.client.serviceUrl.defaultZone=http://localhost:8100/eureka
##服務名稱
spring.application.name=service-zuul
##讀取版本環境(這裏是開發環境或生產環境 git上的文件名稱格式:服務名稱-版本環境.properties)
spring.cloud.config.profile=dev
##讀取分佈式配置中心的服務名稱
spring.cloud.config.discovery.service-id=config-server
##開啓讀取權限
spring.cloud.config.discovery.enabled=true
##定義轉發服務規則
##開啓所有斷點的監控
##management.endpoints.web.exposure.include=*
(3)啓動分佈式配置中心,裏面配置的有讀取git上資源的配置,config配置中心參考: https://mp.csdn.net/postedit/103386487
(4)zuul的啓動類中加入實時更新的代碼:
//zuul配置能夠使用config實現實時更新
@RefreshScope
@ConfigurationProperties("zuul")
public ZuulProperties zuulProperties(){
return new ZuulProperties();
}
這時候可以通過分佈式配置中心從git上來讀取zuul的相關配置信息。
(涉及的服務:Eureka註冊中心、Config分佈式配置中心、Zuul網關、服務提供者、服務消費者)