網關:API Gatewayhtml
系統對外惟一入口,介於客戶端和服務端之間,處理非業務功能前端
提供路由請求,鑑權,監控,緩存,限流等功能spring
簡單理解:小區門衛,防止非法人員入內,居民也能夠問路api
實際理解:假設我部署完成一個電商網站,網關的做用以下緩存
1.前端發起的請求都會發送到網關,好比URL是/api/user,網關判斷後跳轉到用戶服務模塊的服務器服務器
2.雙十一等時期高併發訪問,網關能夠作負載均衡,或者對訪問進行限流降級cookie
3.對權限進行限制,好比用戶不能修改商品庫存,因而網關限制用戶訪問商品編輯模塊服務器併發
Zuul不能憑空使用,至少要有服務模塊以及Eureka Serverapp
這裏我就不重複寫了,使用前文中提到的:負載均衡
搭建Eureka Server和Product-Service:http://www.javashuo.com/article/p-pxvayqiy-mx.html
使用Feign搭建Order-Service:http://www.javashuo.com/article/p-wdnkmplt-mx.html
新建Zuul項目:
Project->New Project->Spring Initializr->命名爲api-gateway
依賴Eureka和Zuul
而後是配置文件:前文都是yml格式的,感受用不慣,仍是繼續用properties吧
主要是配置服務名稱和Eureka Server地址
server.port=9000 spring.application.name=api-gateway eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
在啓動類中加入註解:
package org.dreamtech.apigateway; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication @EnableZuulProxy public class ApiGatewayApplication { public static void main(String[] args) { SpringApplication.run(ApiGatewayApplication.class, args); } }
依次啓動Eureka Server->Product-Service->Order-Service->Api-Gateway項目
Eureka Server:
註冊成功
Zuul的規則是:
zuul-host:zuul-port/service-name/**
我要訪問的是Order-Service的/api/order/save路徑
根據規則應該訪問的是:
http://localhost:9000/order-service/api/order/save?user_id=1&product_id=1:
{"code":0,"data":{"id":0,"productName":"\"iPhone1 data from port=8771\"","tradeNo":"fe70c5d4-7467-43c6-902b-870bb8e763ed","price":1111,"createTime":"2019-05-18T03:16:32.165+0000","userId":1,"userName":null}}
成功
或者訪問:http://localhost:9000/product-service/api/product/find?id=1
{"id":1,"name":"iPhone1 data from port=8771","price":1111,"store":10}
成功
通常狀況下不會用/product-service和/order-service這種路徑,因而想到自定義訪問路徑:
zuul.routes.order-service=/order/**
訪問:http://localhost:9000/order/api/order/save?user_id=1&product_id=1便可
同時,原來的路徑也沒有失效
若是想讓用戶只能經過自定義路徑訪問,而不容許訪問/product-service等路徑
zuul.routes.order-service=/order/** zuul.routes.product-service=/product/** zuul.ignored-patterns=/*-service/**
若是不想開放某服務(不對某服務進行路由)
zuul.ignored-services=order-service
實際部署狀況:各類服務一般在內網中,沒法拿到IP,所以沒法直接訪問
用戶經過公網IP只能訪問到Api-Gateway,經過經過網關訪問服務
就是下圖這種方式
常見的問題解決:
1.多個服務的自定義路徑不能設置成同樣的
2.關於HTTP請求頭的信息的問題
實驗
@RequestMapping("/save") @HystrixCommand(fallbackMethod = "saveOrderFail") public Object save(@RequestParam("user_id") int userId, @RequestParam("product_id") int productId, HttpServletRequest request) { String token = request.getHeader("token"); String cookie = request.getHeader("cookie"); System.out.println(token+" : "+cookie); Map<String, Object> data = new HashMap<>(); data.put("code", 0); data.put("data", productOrderService.save(userId, productId)); return data; }
經過網關來訪問Order-Service(Postman工具):
打印狀況:
hrvboenoiqnjvbwo : null
能夠得出結論:獲取Cookie失敗
緣由:Zuul過濾了請求頭中的Cookie信息
源碼:
private Set<String> sensitiveHeaders = new LinkedHashSet(Arrays.asList("Cookie", "Set-Cookie", "Authorization"));
public void setSensitiveHeaders(Set<String> sensitiveHeaders) { this.sensitiveHeaders = sensitiveHeaders; }
處理:
zuul.sensitive-headers=
注意:不要感受奇怪,這裏就是這麼寫,看源碼set方法置空便可