国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > Java > 正文

SpringCloud實戰之Zuul網關服務

2024-07-14 08:40:54
字體:
來源:轉載
供稿:網友

為什么需要網關呢?

我們知道我們要進入一個服務本身,很明顯我們沒有特別好的辦法,直接輸入IP地址+端口號,我們知道這樣的做法很糟糕的,這樣的做法大有問題,首先暴露了我們實體機器的IP地址,別人一看你的IP地址就知道服務部署在哪里,讓別人很方便的進行攻擊操作。

第二,我們這么多服務,我們是不是要挨個調用它呀,我們這里假設做了個權限認證,我們每一個客戶訪問的都是跑在不同機器上的不同的JVM上的服務程序,我們每一個服務都需要一個服務認證,這樣做煩不煩呀,明顯是很煩的。

那么我們這時候面臨著這兩個及其總要的問題,這時我們就需要一個辦法解決它們。首先,我們看IP地址的暴露和IP地址寫死后帶來的單點問題,我是不是對這么服務本身我也要動態的維護它服務的列表呀,我需要調用這服務本身,是不是也要一個負載均衡一樣的玩意,

還有關于IP地址暴露的玩意,我是不是需要做一個代理呀,像Nginx的反向代理一樣的東西,還有這玩意上部署公共的模塊,比如所有入口的權限校驗的東西。因此我們現在需要Zuul API網關。它就解決了上面的問題,你想調用某個服務,它會給你映射,把你服務的IP地址映射成

某個路徑,你輸入該路徑,它匹配到了,它就去替你訪問這個服務,它會有個請求轉發的過程,像Nginx一樣,服務機器的實例具體實力,它不會直接去訪問IP,它會去Eureka注冊中心拿到服務的實例ID,即服務的名字。我再次使用客戶端的負載均衡ribbon訪問其中服務實例中的一臺。

API網關主要為了服務本身對外的調用該怎么調用來解決的,還有解決權限校驗的問題,你可以在這里整合調用一系列過濾器的,例如整合shiro,springsecurity之類的東西。

網關服務,Zuul,SpringCloud

Zuul可以通過加載動態過濾機制,從而實現以下各項功能:

1.驗證與安全保障: 識別面向各類資源的驗證要求并拒絕那些與要求不符的請求。

2.審查與監控: 在邊緣位置追蹤有意義數據及統計結果,從而為我們帶來準確的生產狀態結論。

3.動態路由: 以動態方式根據需要將請求路由至不同后端集群處。

4.壓力測試: 逐漸增加指向集群的負載流量,從而計算性能水平。

5.負載分配: 為每一種負載類型分配對應容量,并棄用超出限定值的請求。

6.靜態響應處理: 在邊緣位置直接建立部分響應,從而避免其流入內部集群。

7.多區域彈性: 跨越AWS區域進行請求路由,旨在實現ELB使用多樣化并保證邊緣位置與使用者盡可能接近。

接著下來進行實戰小Demo

第一步,在原來的工程下,新建一個Zuul模塊,引入依賴,代碼如下:

<dependency>      <groupId>org.springframework.cloud</groupId>      <artifactId>spring-cloud-starter-eureka</artifactId>      <version>1.3.5.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework.cloud</groupId>      <artifactId>spring-cloud-starter-zuul</artifactId>      <version>1.3.5.RELEASE</version>    </dependency>

接著在啟動類上打上@EnableZuulProxy注解,代碼如下:

server: port: 5000spring: application:  name: api-getewayzuul: routes:#標識你服務的名字,這里可以自己定義,一般方便和規范來講還是跟自己服務的名字一樣  hello-service:#服務映射的路徑,通過這路徑就可以從外部訪問你的服務了,目的是為了不爆露你機器的IP,面向服務的路由了,給你選一個可用的出來,#這里zuul是自動依賴hystrix,ribbon的,不是面向單機   path: /hello-service/**#這里一定要是你Eureka注冊中心的服務的名稱,是所以這里配置serviceId因為跟eureka結合了,如果單獨使用zuul,那么就必須寫自己機器的IP了,#如url:http://localhost:8080/ 這樣的不好就是寫死IP了,萬一這IP掛了,這高可用性,服務注冊那套東西就用不起來了   serviceId: hello-serviceeureka:#客戶端 client:#注冊中心地址  service-url:   defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/

接著啟動先前文章中的注冊中心和兩個hello-service服務提供者,接著我們運行,看一下它的請求轉發功能,看他有沒有輪詢進入兩個服務,

輸入localhost:5000/hello-service/hello,如下:

網關服務,Zuul,SpringCloud

接著再刷新一遍:

網關服務,Zuul,SpringCloud

可以看到zuul進行了請求分發了。它是根據你的服務名字hello-servie來映射到具體的機器上,這不就是一個反向代理的功能嗎?

zuul還能進行請求過濾,那么我們進行一下token校驗來演示一下,首先我們需要先新建一個TokenFilter類來繼承ZuulFilter這個類,實現它的四個接口,代碼如下:

package hjc.zuul;import com.netflix.zuul.ZuulFilter;import com.netflix.zuul.context.RequestContext;import javax.servlet.http.HttpServletRequest;/** * Created by cong on 2018/5/18. */public class TokenFilter extends ZuulFilter {  //四種類型:pre,routing,error,post  //pre:主要用在路由映射的階段是尋找路由映射表的  //routing:具體的路由轉發過濾器是在routing路由器,具體的請求轉發的時候會調用  //error:一旦前面的過濾器出錯了,會調用error過濾器。  //post:當routing,error運行完后才會調用該過濾器,是在最后階段的  @Override  public String filterType() {    return "pre";  }  //自定義過濾器執行的順序,數值越大越靠后執行,越小就越先執行  @Override  public int filterOrder() {    return 0;  }  //控制過濾器生效不生效,可以在里面寫一串邏輯來控制  @Override  public boolean shouldFilter() {    return true;  }  //執行過濾邏輯  @Override  public Object run() {    RequestContext context = RequestContext.getCurrentContext();    HttpServletRequest request = context.getRequest();    String token = request.getParameter("token");    if (token == null){      context.setSendZuulResponse(false);      context.setResponseStatusCode(401);      context.setResponseBody("unAuthrized");      return null;    }    return null;  }}

filterType:返回一個字符串代表過濾器的類型,在zuul中定義了四種不同生命周期的過濾器類型,具體如下:

1. pre :可以在請求被路由之前調用,用在路由映射的階段是尋找路由映射表的

2.route :在路由請求時候被調用,具體的路由轉發過濾器是在routing路由器具體的請求轉發的時候會調用

3. error :處理請求時發生錯誤時被調用

4. post :當routing,error運行完后才會調用該過濾器,是在最后階段的

這里聲明一下zuul過濾器執行網絡請求發生的異常,過濾器里面是不能直接將try-catch捕捉的異常拋出給頁面的。應用程序拋出的異常是可以返回出的需解決辦法就是在catch里面用context.set()方法返回給頁面。如下:

try{  業務邏輯......}catch(Exception e){    RequestContext context = RequestContext.getCurrentContext();     context.set("error.status_code",401);      context.set("error.exception",e);      context.set("error.message","sfdfsdf");}

接著,你還需要把這個過濾器加入spring中,讓spring管理,代碼如下:

package hjc;import hjc.zuul.TokenFilter;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.zuul.EnableZuulProxy;import org.springframework.context.annotation.Bean;@SpringBootApplication@EnableZuulProxypublic class ZuulApplication {  public static void main(String[] args) {    SpringApplication.run(ZuulApplication.class, args);  }  //將過濾器交給Spring管理  @Bean  public TokenFilter tokenFilter(){    return new TokenFilter();  }}

接著,讓我們啟動啟動類,先進行不帶token的訪問,如下:

網關服務,Zuul,SpringCloud

可以看到,返回一個沒權限的信息,這里要說一下,Token一般都是放在請求頭中的,這里我們只是為了演示才沒那么干,

接著將token帶上再去訪問,如下:

網關服務,Zuul,SpringCloud

可以看到這是已經將我們的請求放過去了。

這里我還要講一下什么是默認路由,將zuul的配置刪除路由配置,如下:

server: port: 5000spring: application:  name: api-getewayeureka:#客戶端 client:#注冊中心地址  service-url:   defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/

接著,重啟繼續訪問,如下:

網關服務,Zuul,SpringCloud

可以看到,還是能繼續訪問,我們什么都沒配,居然還能訪問,那是因為,這里默認用你的服務名字hello-service自動聲明了。

那么,如果說我不想讓它幫我自動聲明,我要我自己定義,那么可以在yml配置文件中使用zuu.ignored-services就可以把自己像過濾的過濾,如下:”

zuul:#如果ignored-services:* 表示所有的默認路由都失效了,要自己一個個配,沒人會那么操蛋,除非遇到奇葩業務 ignored-services: 

接著我們再說一下映射規則,比方說

zuul: routes:#標識你服務的名字,這里可以自己定義,一般方便和規范來講還是跟自己服務的名字一樣  hello-service:#服務映射的路徑,通過這路徑就可以從外部訪問你的服務了,目的是為了不爆露你機器的IP,面向服務的路由了,給你選一個可用的出來,#這里zuul是自動依賴hystrix,ribbon的,不是面向單機   path: /hello-service/**#這里一定要是你Eureka注冊中心的服務的名稱,是所以這里配置serviceId因為跟eureka結合了,如果單獨使用zuul,那么就必須寫自己機器的IP了,#如url:http://localhost:8080/ 這樣的不好就是寫死IP了,萬一這IP掛了,這高可用性,服務注冊那套東西就用不起來了   serviceId: hello-servicezuul: routes:  hello-service:   path: /hello-service/ext/**   serviceId: hello-service

這里的兩個zuul配置映射路徑都有/hello-service/,可以看到/hello-service/**是包括/hello-service/ext/**的,這兩個路徑進行匹配的時候是不是有沖突呀,怎么處理呢?誰先匹配呢?

這里是yml中定義的順序來匹配的。如果是application.properties格式的配置文件,它這個順序是不能保證的,yml格式的配置文件是有順序的,可以保證,這里要注意下一下。

如果我們想定義一下匹配規則怎么辦呢?那么我們就需要在啟動類中定義一個bean,這個類就是決定你的路由的,如下:

網關服務,Zuul,SpringCloud

這里就不演示了,需要用到的時候自己再去慢慢查找資料吧。

還有就是ignored-patterns:,如下:

zuul: routes:#標識你服務的名字,這里可以自己定義,一般方便和規范來講還是跟自己服務的名字一樣  hello-service:#服務映射的路徑,通過這路徑就可以從外部訪問你的服務了,目的是為了不爆露你機器的IP,面向服務的路由了,給你選一個可用的出來,#這里zuul是自動依賴hystrix,ribbon的,不是面向單機   path: /hello-service/**#這里一定要是你Eureka注冊中心的服務的名稱,是所以這里配置serviceId因為跟eureka結合了,如果單獨使用zuul,那么就必須寫自己機器的IP了,#如url:http://localhost:8080/ 這樣的不好就是寫死IP了,萬一這IP掛了,這高可用性,服務注冊那套東西就用不起來了   serviceId: hello-service ignored-patterns: /hello/**

ignored-patterns:表示屏蔽掉/hello/**的路徑,就算你/hello-service/hello/**也不行,照樣屏蔽。這個配置我們可以進一步細化,比如說我不想給/hello接口路由,那我們可以按照上面方式配置

如果我們還想配置一個服務的前綴該怎么辦?代碼如下:

zuul: routes:#標識你服務的名字,這里可以自己定義,一般方便和規范來講還是跟自己服務的名字一樣  hello-service:#服務映射的路徑,通過這路徑就可以從外部訪問你的服務了,目的是為了不爆露你機器的IP,面向服務的路由了,給你選一個可用的出來,#這里zuul是自動依賴hystrix,ribbon的,不是面向單機   path: /hello-service/**#這里一定要是你Eureka注冊中心的服務的名稱,是所以這里配置serviceId因為跟eureka結合了,如果單獨使用zuul,那么就必須寫自己機器的IP了,#如url:http://localhost:8080/ 這樣的不好就是寫死IP了,萬一這IP掛了,這高可用性,服務注冊那套東西就用不起來了   serviceId: hello-service prefix: /api/**

可以看到那么你訪問的服務都必須要加/api/前綴,例如/api/hello-service/**

如果我們還想進行一個路徑訪問就跳轉到我的本地,那該怎么辦呢?

我希望用戶在訪問/local時能夠自動跳轉到這個方法上來處理,那么此時我們需要用到Zuul的本地跳轉,配置方式如下:

zuul: prefix: /api ignored-patterns: /**/hello/** routes:  local:   path: /hello-service/**   url: forward:/local

我們常用的一些,對接springsecurity,或者是一些第三方組件,它們會獲取你的一些cookie信息,那么Zuul網關為了安全起見,把你的cookie信息都給干掉了,這個是沒辦法去搞cookie的。它是默認干掉的。

這里Zuul提供了zuul.sensitive-headers來給你搞這些cookie,header,這些信息不要進行過濾。控制你的敏感信息。

默認情況下,敏感的頭信息無法經過API網關進行傳遞,我們可以通過如下配置使之可以傳遞:

zuul: routes:  hello-service:   path: /hello-service/**   serviceId: hello-service sensitive-headers:  cookie,header之類額東西

還可以配合Hystrix的一些詳細配置一起使用,前面也講過了。這里就不說了

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 左权县| 南部县| 酒泉市| 铁力市| 天津市| 老河口市| 十堰市| 温宿县| 霍州市| 谢通门县| 金华市| 玛沁县| 晋江市| 柘荣县| 胶南市| 宜都市| 新田县| 宁安市| 灯塔市| 天长市| 黄陵县| 宁南县| 营口市| 肥西县| 新乡市| 华安县| 佛教| 开鲁县| 庆云县| 顺义区| 鲁山县| 依兰县| 莲花县| 虎林市| 滨海县| 谢通门县| 金山区| 金山区| 高邑县| 龙岩市| 无棣县|