日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Cloud Netflix中文文档翻译笔记

發(fā)布時間:2024/1/8 javascript 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Cloud Netflix中文文档翻译笔记 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文地址:http://cloud.spring.io/spring-cloud-static/spring-cloud-netflix/1.2.2.RELEASE/

Spring Cloud Netflix

1.2.2.RELEASE

Spring Cloude Netflix這個項目提供Netflix OSS和Spring Boot apps集成,通過自動配置和綁定到Spring環(huán)境和其他Spring編程模塊。通過一些簡單的注解配置,你可以很快的使用和配置應(yīng)用的模塊,和構(gòu)建大型分布式高可用的Netflix組件。這里提供包括服務(wù)發(fā)現(xiàn)(Service Discovery Eureka),斷路器或熔斷器(Circuit Breaker Hystrix),智能路由(intelligent routing Zuul)和 負載均衡(Ribbon)。

Service Discovery:Eureka Client

服務(wù)發(fā)現(xiàn)是微服務(wù)架構(gòu)依賴的一個關(guān)鍵模塊。嘗試去管理每個客戶端的配置或者某些形式的約定是非常困難而且不穩(wěn)定。Eureka是Netflix服務(wù)發(fā)現(xiàn)的服務(wù)端和客戶端。服務(wù)端可義高可用的配置和部署,每個服務(wù)器可以相互復(fù)制已注冊的服務(wù)的狀態(tài)。

如何引入Eureka Client

如何在你的項目中使用Eureka Client?使用org.spring.cloud和artifactid spring-cloud-starter-eureka。 請瀏覽網(wǎng)頁spring cloud project page去查看詳情如何配置你的系統(tǒng)使用當前的spring cloud版本。

Eureka注冊

當一個客戶端注冊到Eureka,它就提供了一些自己的元數(shù)據(jù),比如host和port,可用的URL指示器,主頁等。Eureka接收每個注冊到Eureka的實例的心跳包,如果在配置的時間片內(nèi)沒有接收到心跳,這個實例通常就會被注冊中心移除掉。
例子:

@Configuration @ComponentScan @EnableAutoConfiguration @EnableEurekaClient @RestController public class Application {@RequestMapping("/") public String home() {return "Hello world"; }public static void main(String[] args) {new SpringApplicationBuilder(Application.class).web(true).run(args); }}

(i.e 完全普通的spring boot app)。在這個例子中我們顯示的使用用@EnableEurekaClient(explicitly)。但是僅可用的Eureka你可以使用@EnableDiscoveryClient。我們必須通過配置去定位一個Eureka服務(wù)。比如:

application.yml eureka:client:srviceUrl:defaultZone:http://localhost:8761/eureka/

這個 “defaultZone” 是神奇的字符串值,他提供一個服務(wù)地址供其他任何客戶端使用,沒有明確的優(yōu)先級。(i.e. 他是默認可用的)。

這個默認的應(yīng)用名稱(service ID),主機和非安全的端口,分別是 spring.application.name {server.port}

@EnableEurekaClient 使你的應(yīng)用同時變成一個 Eureka 實例(i.e. it registers itself)和 一個客戶端 (i.e. 它可以查詢注冊中心去定位其他服務(wù))。這個實例行為通過 eureka.instance.* 驅(qū)動,但是默認的就夠了,如果確保你的應(yīng)用有一個 spring.application.name (這是個默認的Eureka服務(wù)ID,或則VIP)。

查看 EurekaInstanceConfigBean 和 EurekaClientConfigBean更多配置參數(shù)詳情。

Eureka Server驗證

如果一個eureka客戶端嵌入了認證信息在 “eureka.client.serviceUrl.defaultZone”中,那么HTTP基礎(chǔ)身份驗證會自動添加到eureka客戶端(比如,http://user:password@localhost:8761/eureka)。更多的復(fù)雜的配置你需要創(chuàng)建一個 類型為DiscoveryClientOptionalArgs 的 @Bean,而且注入一個ClientFilter實例,這些都會被應(yīng)用到客戶端到服務(wù)端之間的調(diào)用上。
注意: 由于Eureka的一個限制是不可能支持每個服務(wù)器基本授權(quán)認證,所以只被發(fā)現(xiàn)的第一組會被使用。

狀態(tài)頁和健康指示器

Eureka的狀態(tài)頁和健康指示器默認分別為“/info”和“/health”,是Spring boot actuator默認的配置,它非常好用。即便是一個Actuator應(yīng)用,如果你想使用非默認的上下文路徑或者servlet路徑(如server.servletPath=/foo)或管理端點的路徑(如management.contextPath=/admin),你都需要做出相應(yīng)的改變。例如:

application.yml eureka:instance:statusPageUrlPath:${management.context-path}/infohealthCheckUrlPath:${management.context-path}/health

這些鏈接暴露了客戶端消費的元數(shù)據(jù),和在一些情況下決定是否發(fā)送請求到你的應(yīng)用,所以非常有用如果數(shù)據(jù)精確。

注冊安全應(yīng)用

如果你的app想通過HTTPS連接,你需要設(shè)置兩個標記在EurekaInstanceConfig,即分別是,eureka.instance.[nonSecurePortEnabled,securePortEnabled]=[false,true]。這會使Eureka實例明確的使用安全通道。spring cloud DiscoveryClient總是返回一個https://;服務(wù)的URI配置成這種方式,Eureka實例信息將會有一個安全的檢查URL。
因為Eureka的內(nèi)部工作方式,它將繼續(xù)推送一個非安全的URL的狀態(tài)和主頁,除非你還覆蓋那些聲明。你可以使用占位符娶配置eureka實例的url。 例子:

application.yml eureka:instance:statusPageUrl:https//${eureka.hostname}/infohealthCheckUrl:https//${eureka.hostname}/healthhomePageUrl:https//${eureka.hostname}/

(注意: eureka.hostname使Springplaceholders {eureka.instance.hostName})

注意:如果你的應(yīng)用在慢于一個代理啟動運行,并且SSL終端在代理里面(如:如果你的應(yīng)用作為一個服務(wù)在Cloud Foundry或其它平臺上跑的話),那么你將要確保應(yīng)用能夠攔截和處理代理轉(zhuǎn)發(fā)的頭信息。如果它明確配置有’X-Forwarded-*`這類頭信息的情況下,在一個Spring Boot應(yīng)用里面內(nèi)嵌的Tomcat容器自動處理的。出現(xiàn)這個錯誤的原因,是因為你的應(yīng)用程序提供的鏈接本身弄錯了。(錯誤的主機,端口,協(xié)議)。

Eureka的健康檢查

默認的,Eureka使用客戶端心跳確定一個客戶端是否在線。除非指定了其他的
Discovery Client不會傳播當前的spring boot actuator健康檢查狀態(tài)。這就是說只要成功注冊了Eureka就會一直通知應(yīng)用是在“UP”狀態(tài)。這個動作可以被改變通過使用Eureka health checks,這種發(fā)送應(yīng)用狀態(tài)給Eureka的行為將觸發(fā)Eureka的健康檢查,因此其他每個應(yīng)用程序在其他狀態(tài)下不會給應(yīng)用程序發(fā)送通信然后才‘UP’。

application.yml eureka:client:healthcheck:enabled:true

警告:eureka.client.healthcheck.enabled=true應(yīng)該只在application.yml中被設(shè)置。如果設(shè)置在bootstrap.yml將會引起不可預(yù)知的影響比如注冊eureka出現(xiàn)unknown status。

如果你需要更多的配置關(guān)于health checks,你可能考慮實現(xiàn)你自己的com.netflix.appinfo.HealthCheckHandler。

Eureka實例和客戶端的元數(shù)據(jù)

這里值得我們花一點時間去理解eureka元數(shù)據(jù)是如何工作的,所以你可以在平臺上使用它找點感覺。這里有一個標準的元數(shù)據(jù)比如hostname,ip address,port numbers,status page和health check。他們被發(fā)布到服務(wù)注冊,而且被客戶端聯(lián)系服務(wù)端通過一種直接的方式。另外的,元數(shù)據(jù)可以被添加到實例注冊在eureka.instance.metadataMap,而且這會被遠程客戶端容易訪問,但是通常的不要去改變客戶端的行為,除非你知道了元數(shù)據(jù)的意義。有一些特殊情況下的描述,spring cloud 已經(jīng)分配好了有意義的元數(shù)據(jù)映射。

在Cloudfoundry使用eureka在cloudfoundry

Cloudfoundry有一個全局的根路由器,因此所有相同的app都有一樣的hostname(在其他PaaS解決方案也是類似的架構(gòu))。這不妨礙我們使用Eureka(推薦的,或者強制的依賴你的平臺),你需要明確的設(shè)置hostname和post(secure of non-secure)以便他們使用路由器。你可能也想使用實例元數(shù)據(jù),以便你可以區(qū)分實例在客戶端(在一個定制的負載均衡器)。默認的,eureka.instance.instanceId 是 vcap.application.instance_id。例如:

application.yml eureka:instance:hostname:${vcap.application.uris[0]}nonSecurePort:80

根據(jù)安全規(guī)則的方式設(shè)置你的Cloudfoundry實例,你可能想注冊和使用主機的ip address去直接進行服務(wù)到服務(wù)之間的調(diào)用。這個特性目前還不能在 Pivotal Web Services。

在AWS上使用Eureka

如果應(yīng)用準備發(fā)布到AWS,eureka實例需要配置成Amazon aware,這個可以通過以下方式定制EurekaInstanceConfigBean。

@Bean @Profile("!default") public EurekaInstanceConfigBean eurekaInstanceConfig(){EurekaInstanceConfigBean b = new EurekaInstanceConfigBean();AmazonInfo info = AmazonInfo.Builder.newBuilder().autoBuild("eureka");b.setDataCenterInfo(info);return b; }

改變Eureka實例ID

Netflix Eureka實例是一個身份證,等于其域名注冊(i.e.每個host一個service)。Spring Cloud Eureka提供了一個合適的默認值,想這樣: spring.cloud.client.hostname: {spring.application.name}:{spring.application.instance_id:{server.port}}. 例如: myhost:myappname:8080。

使用spring cloud你可以重寫并提供一個唯一標識通過 eureka.instance.instanceId。

application.yml eureka:instance:instanceId:${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}

通過這些元數(shù)據(jù),和多個在localhost部署的服務(wù)實例,random.value設(shè)置會保證實例唯一。在cloudfoundry中,vcap.appliation.instance_id在spring boot中是自動增長的,所以random.value并不必須。

使用EurekaClient

如果你有一個 @EnalbeDicoveryClient(或@EurekaClient)的應(yīng)用,你可以使用它從Eukeka Server去發(fā)現(xiàn)服務(wù)實例。一種方式是使用原生的com.netflix.discovery.EurekaClient(而不是spring cloud DiscoveryClient)。

@Autowired private EurekaClient discoveryClient;public String serviceUrl(){InstanceInfo instance = discoveryClient.getNextServerFromEureka("STORES",false);return instance.getHomePageUrl(); }

提示:不要使用eurekaClient在@PostConstruct方法或者其他@Scheduled方法(或者任何ApplicationContext還沒有啟動的其他地方)。它初始化在一個SmartLifecycle(phase=0的條件)所以想盡早的使用就必須在另一個更高phase的SmartLifecycle上使用。

原生Netflix EurekaClient的替代品

你不必使用原始的Netflix EurekaClient,通常使用一個包裝器會更方便。Spring Cloud提供Fegin(REST客戶端構(gòu)建器)和Spring RestTemplate去使用Eureka service的邏輯標識符替代物理URLS。配置帶固定的物理服務(wù)器集合的Ribbon,你可以簡單的設(shè)置.ribbon.listOfServers的物理服務(wù)器地址(或者hostname)集合,并使用逗號分隔符分開,是客戶端的ID。

你也可以使用 org.springframework.cloud.client.discoveryClient,它提供了一個簡單的API而不是特定于Netflix。

@Autowired private DiscoveryClient discoveryClient;public String serviceUrl(){List<ServiceInstane> list = discoveryClient.getInstances("STORES");if(list!=null && list.siz()>0) {return list.get(0).getUri();}return null; }

為什么注冊一個服務(wù)很慢

成為一個實例也包含一個到注冊中心的心跳(serviceUrl),默認30秒。一個服務(wù)不會被客戶端發(fā)現(xiàn),直到實例、服務(wù)端和客戶端全都擁有相同的元數(shù)據(jù)在它們的緩存里面(這可能還需要3次心跳)。你可以改變這個周期通過 eureka.instance.leaseRenewalIntervalInSeconds,這會加速client連接到其他的services。在生產(chǎn)環(huán)境或許最好保持默認值,因為server有些本地的計算去確保假設(shè)的更新周期(make assumptions about the lease renewal period)。

服務(wù)發(fā)現(xiàn):Eureka Server

如何引入Eureka Server

引入Eureka Server到你的項目你需要使用org.springframework.cloud和spring-cloud-starter-eureka-server。訪問spring cloud project page查看更多詳情。

如何運行Eureka Server

eureka server示例:

@SpringBootApplication @EnableEurekaServer public class Application{public static void main(String [] args) {new SpringApplicationBuilder(Application.class).web(true).run(args);} }

Server有一個UI主頁,和HTTP API端點提供平常的功能,地址:/eureka/*

Eureka背景:flux capacitor和google group discussion

TIP:由于Gradle的依賴解析規(guī)則,它沒有父bom依賴的特性,簡單的spring-cloud-starter-eureka-server依賴會引發(fā)錯誤。為了補救,必須添加Spring Boot的Gradle插件,而且引入Spring cloud starter的父bom。like so:

build.gradle buildscript{dependencies{classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.5.RELEASE")} }apply plugin: "spring-boot"dependencyManagement{imports{mavenBom "org.springframework.cloud:spring-cloud-dependencies:Brixton.RELEASE" } }

高可用,Zones和Regions

Eureka server沒有一個后端的存儲,但是服務(wù)實例在注冊里面全都得發(fā)送心跳去保持注冊更新(在內(nèi)存里操作)。Clients同樣有一個erureka注冊中心的內(nèi)存緩存(所以他們不是去為每一個到service的請求都去一次注冊中心)。
默認的,每一個Eureka server同樣是一個Eureka client,而且需要(至少一個)service url去定位同伴。如果你沒有提供,service同樣會運行和工作,但他會產(chǎn)生很多無法與其他同伴注冊的錯誤日志。

也可查看 客戶端Riboon支持,Zones 和 Regions。

獨立模式

client和server結(jié)合的緩存和心跳會使一個單機的Eureka server很好的彈性失敗(fairly resilient to failure),有一些監(jiān)視和elastic runtime會使它保持活躍(比如:cloud foundry)。在獨立模式下,,您可能更傾向于關(guān)閉客戶端的行為,所以它不能保持失敗重試和重新找回它的那些節(jié)點。如:

application.yml server:port:8761eureka:instance:hostname:localhostclient:registerWithEureka:falsefetchRegistry:falseserviceUrl:defaultZone:http://${eureka.instance.hostname}:${server.port}/eureka/

注意:serviceUrl指向了自己本地的實例。

Peer Awareness

Eureka可以有很好的彈性和可用性通過運行多個實例,和請求他們?nèi)ハ嗷プ浴J聦嵣?#xff0c;這是默認的行為,所以所有你需要做的就是添加一個可用的serviceUrl到每一個同伴讓它可以工作。

applicatin.yml(Two Peer Aware Eureka Servers) --- spring:profiles: peer1 eureka:instance:hostname: peer1client:serviceUrl:defaultZone: http://peer2/eureka/--- spring:profiles: peer2 eureka:instance:hostname:peer2client:serviceUrl:defaultZone: http://peer1/eureka

在這個例子中,我們有一個YAML文件,它可以用來運行同樣的兩個server在兩個hosts上(peer1 和 peer2),兩個不同的Spring profiles。你可以使用這個配置測試單機上的兩個對等實例(沒有多少價值在生產(chǎn)環(huán)境中這樣做)。通過修改/etc/hosts改變hostnames。事實上,eureka.instance.hostname并不需要如果你運行你自己直到的主機名的機器(它默認使用java.net.InetAddress檢查)。

你可以添加多個實例到一個系統(tǒng)上,而且只要他們都彼此連接到至少一個邊緣,他們將會同步注冊信息。If the peers are physically separated (inside a data centre or between multiple data centres) then the system can in principle survive split-brain type failures.

Prefer IP Address

一些情況,相比hostname,Eureka更好的是使用IP Adresses。設(shè)置 eureka.instance.preferIpAddress=true,當應(yīng)用注冊到eureka上的時候,他們將使用IP Address替代hostname。

電子斷路器:Hystrix Clients

Netflix創(chuàng)建了一個庫叫Hystrix實現(xiàn)了電子斷路器模塊。在一個微服務(wù)架構(gòu)中它一般有多個服務(wù)調(diào)用層。

一個底層的服務(wù)錯誤會引起級聯(lián)錯誤一直反饋到用戶。當調(diào)用一個特定的服務(wù)到達一定的閥值后(20 failures in 5 seconds is the default in Hystrix),回路開啟然后調(diào)用也不會成功。一些錯誤情況下可以由程序員提供
open circuit a fallback。

Having an open circuit stops cascading failures and allows overwhelmed or failing services time to heal. The fallback can be another Hystrix protected call, static data or a sane empty value. Fallbacks may be chained so the first fallback makes some other business call which in turn falls back to static data.

如何引入Hystrix

在你的項目中通過 org.springframework.cloud 和 spring-cloud-starter-hystrix 引入Hystrix。查看詳情并設(shè)置你的系統(tǒng)使用當前的spring cloud Release。
例如:

@SpringBootApplication @EnableCircuitBreaker public class Application {public static void main(String[] args) {new SpringApplicationBuilder(Application.class).web(true).run(args);} }@Component public class StoreIntegration{@HystrixCommand(fallbakMethod="defaultStores")public Object getStore(Map<String,Object> parameters){//do stuff that might fail}public Object defaultStores(Map<String,Object> paramters) {return /*something useful*/;} }

Netflix的普通發(fā)布庫叫Javanica提供了@HystrixCommand注解。Spring Cloud使用注解自動適配spring bean使用代理去連接到Hystrix斷路器。斷路器計算何時打開和關(guān)閉斷路,并決定在失敗的情況下做什么。

配置@HystrixCommand你可以使用commandProperties屬性,它有@HystrixProperty的注解列表。通過這里查看更多詳情.訪問Hystrix wiki查看更多可用的屬性。

Propagating the Security Context or using Spring Scopes

如果你想把本地線程上下文傳播到@HystrixCommand,默認的聲明將不可用因為它是在一個線程池中被啟動的。你可以選擇讓Hystrix使用同一個線程,通過一些配置,或直接寫在注解上,通過使用isolation strategy屬性。例如:

@HystrixCommand(fallbackMethod="stubMyService",commandProperties={@HystrixProperty(name="execution.isolation.strategy",value="SEMAPHORE")})

同樣的方式適用于如果你用@SessionScope 或者 @RequestScope。你應(yīng)該知道什么時候去做這件事因為有些運行時異常報找不到scoped上下文。

你還可以選擇設(shè)置 hystrix.shareSecurityContext 屬性為true。設(shè)置這個值會自動配置一個Hystrix兵法策略會把securityContext從主線程傳輸?shù)侥闶褂玫腍ystrix command。Hystrix does not allow multiple hystrix concurrency strategy to be registered so an extension mechanism is available by declaring your own HystrixConcurrencyStrategy as a Spring bean. Spring Cloud will lookup for your implementation within the Spring context and wrap it inside its own plugin

Health Indicator

斷路器的狀態(tài)同樣暴露在/health端點上。

{ "hystrix": {"openCircuitBreakers": ["StoreIntegration::getStoresByLocationLink"],"status": "CIRCUIT_OPEN" }, "status": "UP" }

Hystrix Metrics Stream

使用Hystrix metrics stream需要引入依賴 spring-boot-starter-actuator。這會暴露/hystrix.stream作為一個管理端點。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId> </dependency>

Circuit Breaker: Hystrix Dashboard

Hystrix的主要好處就是她收集了關(guān)于每個HystrixCommand的指標。Hystrix儀表盤用一種高效的方式展示了斷路器的健康數(shù)據(jù)。

如何引入Hystrix儀表盤

…org.springframework.cloud and artifact id spring-cloud-starter-hystrix-dashboard…Spring Cloud Project page

在Spring boot main class上加@EnableHystrixDashboard可以運行Hystrix儀表盤,然后可以訪問/hystrix并把儀表盤指向一個個體實例/hystrix.stream端點在一個應(yīng)用中。

Turbine

看一個實例Hystrix數(shù)據(jù)對于整個系統(tǒng)的健康不是很有用. Turbine 是一個應(yīng)用程序,該應(yīng)用程序匯集了所有相關(guān)的/hystrix.stream端點到 /turbine.stream用于Hystrix儀表板。運行turbine使用@EnableTurbine注解你的主類,使用spring-cloud-starter-turbine這個jar。配置請參考 the Turbine 1 wiki 唯一的區(qū)別是turbine.instanceUrlSuffix不需要端口號前綴,因為這是自動處理,除非turbine.instanceInsertPort=false。

turbine.appConfig配置是一個eureka服務(wù)ID列表,turbine將使用這個配置查詢實例。turbine stream在hystrix dashboard中使用如下的url配置: http://my.turbine.server:8080/turbine.stream?cluster=,如果集群的名稱是default,集群參數(shù)可以忽略)。這個cluster參數(shù)必須和turbine.aggregator.clusterConfig匹配。從eureka返回的值都是大寫的,因此我們希望下面的例子可以工作,如果一個app使用eureka注冊,并且被叫做”customers”:

turbine:aggregator:clusterConfig: CUSTOMERSappConfig: customers

clusterName可以使用SPEL表達式定義,在turbine.clusterNameExpression。 默認值是appName,意思是eureka服務(wù)ID最終將作為集群的key,例如customers的 InstanceInfo有一個CUSTOMERS的appName。另外一個例子是turbine.clusterNameExpression=aSGName,將從AWS ASG name獲取集群名稱。作者例子:

turbine:aggregator:clusterConfig: SYSTEM,USERappConfig: customers,stores,ui,adminclusterNameExpression: metadata['cluster']

在這種情況下,集群名稱從4個服務(wù)從其元數(shù)據(jù)映射,期望包含“SYSTEM”和“USER”。

所有的app使用default,你需要一個文字表達式(使用單引號):

turbine:appConfig: customers,storesclusterNameExpression: "'default'"

spring cloud提供一個spring-cloud-starter-turbine,所有依賴項你需要運行一個turbine服務(wù)器。使用@EnableTurbine創(chuàng)建一個spring boot應(yīng)用。

注意:默認情況下Spring Cloud 允許 Turbine 在集群的每個主機下使用主機名和端口運行多個進程。如果你想在集群中的每個主機使用本機原生Netfix行為且不允許多個進程創(chuàng)建運行Turbine。(實例id的key為主機名)然后設(shè)置屬性turbine.combineHostPort=false

Turbine Stream

在一些環(huán)境(Pass), 在所有分布式下典型的Turbine 模型的Hystrix 命令都不工作,在這種情況下,你可能想要 Hystrix 命令 推送到 Tuibine, 和Spring Cloud進行消息傳遞,那么你需要要做的是在客戶端添加一個依賴spring-cloud-netflix-hystrix-stream和你所選擇的 spring-cloud-starter-stream-*的依賴(相關(guān)信息請查看 Spring Cloud Stream 方檔,以及如何配置客戶端憑證,和工作時的要本地代理)

創(chuàng)建一個帶有注解 @EnableTurbineStream 的Spring boot 應(yīng)用服務(wù)器,端口默認 8989 (Hystrix 儀表盤的URL都使用此端口), 如果你想自定義端口,可以配置 server.port 或 turbine.stream.port 任一個,如果你使用了 spring-boot-starter-web 和 spring-boot-starter-actuator ,那么你可以提供(使用Tomcat默認情況下) management.port 不同的端口,并打開這個單獨的執(zhí)行器端口

你可以把Dashboard指向Turbine Stream Server來代替?zhèn)€別Hystrix streams。如果Tubine Stream 使用你本機的8989端口運行,然后把 http://myhost:8989在流輸入字段Hystrix儀表板 Circuits 將由各自的 serverId關(guān)綴,緊隨其后的是一個點,然后是circuit 名稱

客戶端負載均衡:Ribbon

Ribbon是一個客戶端的負載均衡器,可以提供很多HTTP和TCP的控制行為。Feign已經(jīng)使用了Ribbon,所以如果你使用了@FeignClient,Riboon也同樣被應(yīng)用了。

Ribbon核心的概念是named client。每個負載均衡器都是共同體的一部分,可以一起運行去連接遠程服務(wù)器,你會給你的應(yīng)用設(shè)置一個名字(比如使用@FeignClient注解)。Spring Cloud creates a new ensemble as an ApplicationContext on demand for each named client using RibbonClientConfiguration. This contains (amongst other things) an ILoadBalancer, a RestClient, and a ServerListFilter.

如何引入Ribbon

org.springframework.cloud and artifact id spring-cloud-starter-ribbon. 查看詳情 Spring Cloud Project page

定制Ribbon Clietn

你可以配置一些Ribbon client的屬性在外部的屬性文件里(application.properties/yml),如.ribbon.*,這個和Netflix APIS本身沒有什么不同。本機選項可以被檢查使用CommonClientConfigKey等靜態(tài)字段。

Spring cloud還允許你完全控制客戶端通過聲明額外的配置,使用@RibbonClient(位于RibbonClientConfiguration的頂部)。
例如:

@Configuration @RibbonClient(name="foo",configuration=FooConfiguration.class) public class TestConfiguration{ }

In this case the client is composed from the components already in RibbonClientConfiguration together with any in FooConfiguration (where the latter generally will override the former).

警告:FooConfiguration已經(jīng)設(shè)置為@Configuration,但是注意它不是@ComponentScan在主程序上下文,另外它會被所有的@RibbonClients共享。如果你使用了@ComponentScan(或者@SpringBootApplication)你需要采取措施去避免引入。(例如把他分割開來,不要重疊包,或者指定明確的包路徑在@ComponentScan)。

Spring Cloud Netflix默認為Ribbon提供了如下beans(BeanType beanName:ClassName):
* IClientConfig ribbonClientConfig: DefaultClientConfigImpl
* IRule ribbonRule: ZoneAvoidanceRule
* IPing ribbonPing: NoOpPing
* ServletList ribbonServerList: ConfigurationBasedServerlList
* ServerListFilter ribbonServerListFilter:
* ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer

創(chuàng)建一個這些類型的一個Bean放置到@RibbonClient配置類中(就像上面的FooConfiguration一樣),它允許你重寫每一個bean的描述。例如:

@Configuration public class FooConfiguation {@Beanpublic IPing ribbonPing(IClientConfig config){return new PingUrl();} }

這里使用PingUrl替換了NoOpPing。

Customizing the ribbon client using properties

從1.2.0版本開始,sping cloud netflix支持使用配置文件的方式定制RibbOn clients并且與文檔兼容 Ribbon documentation

這允許你在不同環(huán)境中,改變啟動時的行為。

這些屬性都列在下面,并且他們必須使用 .ribbon.作為前綴。
* NFLoadBalancerClassName: should implement ILoadBalancer
* NFLoadBalanceerRuleClassName: should implement IRuld
* NFLoadBalancePingClassName: should implement IPing
* NIWSServerListClassName: should implement ServerList
* NIWServerListFilterClassName: should implement ServerListFilter

注意: 類中定義了這些屬性將會優(yōu)先于@RibbonClient(configuration=MyRibbonConfig.class),默認的是Spring Cloud Netflix提供了。

給服務(wù)名為user設(shè)置IRule,你可以如下設(shè)置:

application.yml user:ribbon:NFLoadBalancerRuleClassName:com.netflix.loadbalancer.WeightedResponseTimeRule

從 Ribbon documentation 查看Ribbon的實現(xiàn)。

Using Ribbon with Eureka

當Eureka跟Ribbon結(jié)合使用的時候(都在classpath),ribbonServerList會被一個外部的DiscoveryEnabledNIWServerList重寫,它填充了服務(wù)懶得列表從Eureka中。它同樣使用了NIWDiscoveryPing替換了IPing,它讓Eureka去確定一個server是否啟動。serverList默認使用的是DomainExtractingServerList,目的是讓物理元數(shù)據(jù)用于負載均衡器而不是AWS AMI(這是Netflix依賴的)。默認srverlist會構(gòu)造”zone”信息提供給實例使用(遠程客戶端設(shè)置eureka.instance.metadataMap.zone),如果沒有設(shè)置它可以使用域名服務(wù)器的主機名作為區(qū)域代理(如果approximateZoneFromHostname被設(shè)置了)。一旦zone信息可用,它也會被用在ServerListFilter。默認它會用來定位一個客戶端在同一個zone,因為默認的是ZonePrefeerenceServerListFilter。client的zone默認跟遠程實例的一樣。i.e. eureka.instance.metadataMap.zone。

注意:正統(tǒng)的“archaius”方式設(shè)置client zone是通過配置屬性”@zone”,Sping Cloud將會優(yōu)先使用這個設(shè)置(它會去引用YAML的配置)。

注意:If there is no other source of zone data then a guess is made based on the client configuration (as opposed to the instance configuration). We take eureka.client.availabilityZones, which is a map from region name to a list of zones, and pull out the first zone for the instance’s own region (i.e. the eureka.client.region, which defaults to “us-east-1” for comatibility with native Netflix).

Example:How to Use Ribbon Without Eureka

Eureka是一個方便的方式去抽象遠程服務(wù)發(fā)現(xiàn),所以你不需要在客戶端硬編碼他們的URLS。但是如果你不想用eureka,Ribbon和Feign仍然可用。假設(shè)你已經(jīng)在“stores”定義了@RibbOnClient,而且沒有使用Eureka(沒有在classpath中)。Ribbon client默認要配置server list,你可以提供配置像這樣:

application.yml stores:ribbon:listOfServers: example.com.google.com

Example:Disable Eureka use in Ribbon

設(shè)置property ribbon.eureka.enable=false將會明確的讓Eureka的ribbon失效。

application.yml ribbon:eureka:enabled: false

Using the Ribbon API Directly

你也可以直接使用 LoadBalancerClient。例如:

public class MyClass {@Autowiredprivate LoadBalancerClient loadBalancer;public void dostuff(){ServiceInstance instance = loadBalancer.choose("stors");URI storeUri = URI.create(String.format("httP://%s:%s",instance.getHost(),instance.getPort()));//... do something with the URI} }

Declarative REST Client:Feign

Feign是一種聲明式的web service client。它讓web service變得更容易。使用Feign你只需要創(chuàng)建一個接口并且寫上注解。它提供插拔式的Feign注解和JAX-RS注解支持。Feign同樣提供插拔式的編碼解碼器。Spring Cloud添加了Spring MVC的注解支持,在Spring web中默認使用相同的HttpMessageConverters。spring cloud集成了Ribbon 和 Eureka去提供負載均衡。

How to include Feign

org.springframework.cloud and artifact id spring-cloud-starter-feign。Spring Cloud Project page。

Example spring boot app:

@Configuration @ComponentScan @EnableAutoConfiguration @EnableEurekaClient @EnableFeignClients public class Application {public stati void main(String[] args){SpringApplication.run(Application.class,args);} }

StoreClient.java

@FeignClient("sotes") public interface StoreClient{@RequestMapping(method=RequestMethod.GET,value="/stores")List<Store> getStores();@RequestMapping(method=RequestMethod.POST,value="/stores/{storeId}",consumes="appliation/json")Store update(@PathVariable("storeId") Long storeId,Store store); }

在@FeignClient注解里是一個任意的服務(wù)端的名字(比如 “store”),用于創(chuàng)建一個Ribbon負載均衡。你也可以指定一個URL,通過使用url屬性(絕對值或者只是個hostname)。應(yīng)用程序上下文中的bean的名稱是接口的完全限定名稱。一個別名同樣被創(chuàng)建就是 “name”屬性上附加上“FeignClient”。看上面的列子,@Qualifire(“storesFeignClient”)可以用來引用bean,如果你想改變默認@Qualifier值,這可以在@FeignClient使用qualifier值。

Ribbon client會發(fā)現(xiàn)“stores”服務(wù)的物理地址。如果你的應(yīng)用是Eureka client然后Eureka注冊中心會決定service的地址。如果你不想使用Eureka,你可以簡單的配置一個 server list 在你的外配配置中。

Overriding Feign Defaults

Sping cloud Feign支持的一個核心概念就是聲明的客戶端。每一個Feign client是整體的的一部分一起通過遠程服務(wù)器聯(lián)系,使用@FeignClient注解指定一個整體使用的名字。Sping cloud為每一個使用FeignClientConfiguration聲明的客戶端創(chuàng)建一個新的ApplictionContxt。這包括(除去其他東西)feign.Decode,feign.Encoder和feign.Contract。

Spring cloud提供通過@FeignClient.添加添額外的配置的方法讓你完全控制feign client。例如:

@FeignClient(name="stores", configuration=FooConfiguration.class) public interface StoreClient{ }

在這個例子中,FeignClientsConfiguration已經(jīng)有的和FooConfiguration自定義的共同組成了client(后者會覆蓋先者)。

警告: FooConfiguration必須是@Configuration,但是注意不能在@CompinentScan中,否則將被用于每個@FeignClient。如果你使用@ComponentScan(或@ SpringBootApplication),你需要采取一些措施來避免它被列入(比如把它放在一個單獨的,非重疊的包,或者指定包在@ComponentScan明確掃描)。

注意:該 serviceId 已經(jīng)過時,建議使用 name 屬性

警告:以前,使用 url 屬性,則 name 不是必須的,但現(xiàn)在是必須的.

name 和 url 屬性都支持占位符。

@FeignClient(name="${feign,name}",url="${feign.url}") public interface StoreClient{ }

Spring cloud netflix默認給feign提供如下bean(BeanType beanName:ClassName)
* Decoder feignDecoder: RespinseEntityDecoder(包裝了SpringDeccoder)
* Encoder fergnEncoder: SpringEncoder
* Logger feignLogger: SLF4JLogger
* contract feignContract:SpringMvcContract
* Feign.Builder feignBuilder: HystrixFeign.Builder
* Client feignClient:如果Ribbon可用就是loadBalancerFeignClient,否則默認feign client。

OkHttpClient和ApacheHttpClient feign clients可以通過分別設(shè)置fiegn.okhttp.enable 或者 feign.httpclient.enable為true,并且添加到classpath。

Spring cloud netflix默認沒有提供一下bean,但是仍然可以從上下文中查找這些bean并創(chuàng)建feign client:
* Logger.Level
* Retryer
* ErrorDecoder
* Request.options
* Collection

創(chuàng)建這些類型的一個bean可以放在@FeignClient配置中(如上FooConfiguration),允許你覆蓋所描述的每一個bean. 例子:

@Configuration public class FooConfiguration{@Beanpublic Contract feignContract(){return new feign.Contract.Default(); }@Beanpublic BasicAuthRequestInterceptor basicAuthRequestInterceptor(){return new BasicAuthRequestInterceptor("user","password");} }

可以替換SpringMvcContract 和 feign.Contract.Default, 并增加一個 RequestInterceptor 到 RequestInterceptor 中去.

可以通過@EnableFeignClients的屬性defaultConfiguration以同樣的方式被指定。不同之處是配置會加載到所有的feign clients。

Creating Feign Clients Manually

在一些情況下可能需要自定義Feign clients但是不能用以上的方法。所以你可以使用Feign Builder API創(chuàng)建clients。下面是一個例子,創(chuàng)建了兩個相同接口的client但是用配置了分開的攔截器。

@Import(FeignClientsConfiguration.class) class FooController {private FooClient fooClient;private FooClient adminClient;@Autowired public FooController(ResponseEntityDecoder decoder, SpringEncoder encoder, Client client) {this.fooClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).requestInterceptor(new BasicAuthRequestInterceptor("user", "user")).target(FooClient.class, "http://PROD-SVC");this.adminClient = Feign.builder().client(client).encoder(encoder).decoder(decoder).requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin")).target(FooClient.class, "http://PROD-SVC");} }

注意:在這個例子中,FeignClientsConfiguration.class是Spring Cloud Netflix默認提供的配置。

PROD-SVC是我們提供的服務(wù)名稱,會接收相應(yīng)的客戶端的請求。

Feign Hystrix Support

如果Hystrix在classpath中,默認Feign用熔斷器包裝所有方法。返回一個 com.netflix.hystrix.HystrixCommand 也是可用的。這允許你以被動模式使用(使用.toObservable()或者.observer())或者 異步調(diào)用(.queue())。

要禁用Feign 的 Hystrix支持,設(shè)置feign.hystrix.enabled=false.

要在每個客戶端上禁用 Hystrix 支持,創(chuàng)建一個 Feign.Builder 并將scope 設(shè)置為”prototype”,例如:

@Configuration public class FooConfiguration {@Bean@Scope("prototype")public Feign.Builder feignBuilder() {return Feign.builder();} }

Feign Hystrix Fallbacks

Hystrix支持回退的概念:一段默認的代碼將會被執(zhí)行當斷路器打開或者發(fā)生錯誤。要啟用回退要給@FeignClient設(shè)置fallback屬性來實現(xiàn)回退.

@FeignClient(name="hello",fallback=HystrixClientFallback.class) protected interface HystrixClient {@RequestMapping(Method=RequestMethod.GET,value="/hello")Hello iFailSometimes(); }static class HystrixClientFallback implements HystrixClient{@Overridepublic Hello iFailSometimes(){return new Hello("fallback");} }

如果一個請求需要觸發(fā)回退,可以使用fallbackFactory屬性替換@FeignClient。

@FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class) protected interface HystrixClient {@RequestMapping(method = RequestMethod.GET, value = "/hello")Hello iFailSometimes(); }@Component static class HystrixClientFallbackFactory implements FallbackFactory<HystrixClient> {@Overridepublic HystrixClient create(Throwable cause) {return new HystrixClientWithFallBackFactory() {@Overridepublic Hello iFailSometimes() {return new Hello("fallback; reason was: " + cause.getMessage());}};} }

警告:There is a limitation with the implementation of fallbacks in Feign and how Hystrix fallbacks work. Fallbacks are currently not supported for methods that return com.netflix.hystrix.HystrixCommand and rx.Observable.

Feign Inheritance Support

Feign支持通過單繼承接口引用api,這允許將通用操作分組為方便的基本接口.

UserService.java public interface UserService {@RequestMapping(method = RequestMethod.GET, value ="/users/{id}") User getUser(@PathVariable("id") long id); }UserResource.java @RestController public class UserResource implements UserService {}UserClient.java package project.user;@FeignClient("users") public interface UserClient extends UserService {}

注意:通常在一個server和一個client之間共享一個接口是不可取的。它引入了緊耦合,實際上它也不會spring mvc中起作用(方法參數(shù)映射不會被繼承)。

Feign request/response compression

你可能考慮對你的Feign請求啟用GZIP壓縮。你可以通過設(shè)置如下啟用:

feign.compression.request.enabled=true feign.compression.response.enabled=true

Feign提供的壓縮設(shè)置與你的Web server的設(shè)置類似:

feign.compression.request.enabled=true feign.compression.request.mime-types=text/xml,application/xml,application/json feign.compression.request.min-request-size=2048

這些屬性允許你選擇要壓縮的 MIME-TYPE 和最小的請求長度。

Feign logging

每個Feign client都創(chuàng)建了一個logger。默認的logger的命名是Feign client的全限定名。Feign日志只響應(yīng) DEBUG 級別。

application.yml logging.level.project.user.UserClient: DEBUG

你能為每個客戶端配置Logger.Level 對象,告訴Feign記錄多少日志,選項包括:
* NONE, 不記錄 (DEFAULT).
* BASIC, 僅記錄請求方式和URL及響應(yīng)的狀態(tài)代碼與執(zhí)行時間.
* HEADERS, 日志的基本信息與請求及響應(yīng)的頭.
* FULL, 記錄請求與響應(yīng)的頭和正文及元數(shù)據(jù).

例如,下面的設(shè)置會讓 Logger.Level為FULL.

@Configuration public class FooConfiguration {@BeanLogger.Level feignLoggerLevel() {return Logger.Level.FULL;} }

External Configuration: Archaius

Archaius是Netflix client端配置庫。它的配置可以被所有的Netflix OSS組件使用。Archaius是 Apache Commons Configuration 的項目。它允許更新配置通過輪詢或者推送到client的方式。Archaius使用動態(tài)屬性類屬性的處理屬性。

Archaius Example class ArchaiusTest {DynamicStringProperty myprop = DynamicPropertyFactory.getInstance().getStringProperty("my.prop");void doSomething() {OtherClass.someMethod(myprop.get());} }

Archaius有它自己的一套配置文件和負載優(yōu)先級, Spring 應(yīng)用程序通常不應(yīng)直接應(yīng)用Archaius, 本身仍然有配置Netflix工具的需求。Spring Cloud有一個Spring Environment Bridge,所以Archaius可以通過spring environment讀取屬性。這允許spring boot項目使用配置工具鏈,while allowing them to configure the Netflix tools, for the most part, as documented.

Router and Filter: Zuul

路由是微服務(wù)架構(gòu)的不可或缺的一部分。例如:/ 可能映射到你應(yīng)用主頁,/api/users映射到用戶服務(wù),/api/shop映射到購物服務(wù)。Zuul。Zuul是Netflix出品的一個基于JVM路由和服務(wù)端的負載均衡器。

Netflix uses Zuul for the following:
* Authentication
* Insights
* Stress Testing
* Canary Testing
* Dynamic Routing
* Service Migration
* Load Shedding
* Security
* Static Response handling
* Active/Active traffic management

Zuul的規(guī)則和過濾器允許使用各種基于JVM的語言,支持基于Java和Groovy。

注意:zuul.max.host.connections已經(jīng)被兩個新的屬性替代:zuul.host.maxTotalConnections 和 zuul.host.maxPerRouteConnections,默認分別為200和20.

注意:默認所有routes的Hystrix隔離模式(ExecutionIsolationStrategy)是SEMAPHORE zuul.ribbonIsolationStrategy可以改為THREAD,如果這個隔離模式更好。

How to Include Zuul

org.springframework.cloud and artifact id spring-cloud-starter-zuul。See the Spring Cloud Project page for details。

Embedded Zuul Reverse Proxy

當一個UI應(yīng)用想要代理調(diào)用一個或者多個后臺服務(wù)的時候,Sping cloud創(chuàng)建了一個嵌入的Zuul proxy很方便的開發(fā)一個簡單的案例。這個功能對于代理前端需要訪問的后端服務(wù)非常有用,避免了所有后端服務(wù)需要關(guān)心管理CORS和認證的問題.

在Spring Boot主函數(shù)上通過注解 @EnableZuulProxy 來開啟, 這樣可以讓本地的請求轉(zhuǎn)發(fā)到適當?shù)姆?wù). 按照約定, 一個ID為”users”的服務(wù)會收到 /users 請求路徑的代理請求(前綴會被剝離). Zuul使用Ribbon定位服務(wù)注冊中的實例, 并且所有的請求都在hystrix的command中執(zhí)行, 所以失敗信息將會展現(xiàn)在Hystrix metrics中, 并且一旦斷路器打開, 代理請求將不會嘗試去鏈接服務(wù).

注意:Zuul starter沒有包含服務(wù)發(fā)現(xiàn)的客戶端, 所以對于路由你需要在classpath中提供一個根據(jù)service IDs做服務(wù)發(fā)現(xiàn)的服務(wù).(例如, eureka是一個不錯的選擇)

去忽略一個自動添加的服務(wù),可以在服務(wù)ID表達式列表中設(shè)置 zuul.ignored-services。如果一個服務(wù)匹配到了要忽略的列表, 但是它也明確的配置在路由列表中, 將不會被忽略, 例如:

application.yml zuul:ignoredServices: '*'routes:users: /myusers/**

在這個例子中,所有的服務(wù)都會被忽略,除了“users”。

增加或改變代理路由規(guī)則, 你可以添加類似下面的外部配置:

application.ymlzuul:routes:users: /myusers/**

這表示,HTTP調(diào)用 “/myusers” 會轉(zhuǎn)到 “user” 服務(wù)(例如:”/myusers/101”跳轉(zhuǎn)到”/101”)。

為了更細粒度的控制一個路由, 你可以獨立指定配置路徑和服務(wù)ID:

application.ymlzuul:routes:users:path: /myusers/**serviceId: users_service

這表示,HTTP調(diào)用 “/myuser”會跳轉(zhuǎn)到”users_servie”服務(wù)。路由必須配置一個可以被指定為”ant路徑匹配原則”的”path”,所以“/myusers/”只能匹配一個層級, 但”/myusers/*“可以匹配多級.(附注:Ant path 匹配原則)

后端的配置既可以是”serviceId”(對于服務(wù)發(fā)現(xiàn)中的服務(wù)), 也可以是”url”(物理地址), 例如:

application.ymlzuul:routes:users:path: /myusers/**url: http://example.com/users_service

url-routes的方式不會執(zhí)行 HystrixCommand 也不會通過Ribbon負載多個URLS。要實現(xiàn)這些,需給這個serviceid指定一個service-route并配置一個Ribbon client(這個必須在Ribbon中禁用Eureka: see above for more information)。

application.yml zuul:routes:users:path: /myusers/**serviceId: usersribbon:eureka:enabled: falseusers:ribbon:listOfServers: example.com,google.com

你可以使用regexmapper提供serviceId和routes之間的綁定. 它使用正則表達式組來從serviceId提取變量, 然后注入到路由表達式中.

@Bean public PatternServiceRouteMapper serviceRouteMapper() {return new PatternServiceRouteMapper("(?<name>^.+)-(?<version>v.+$)","${version}/${name}"); }

這表示serviceId “myusers-v1” 將會被映射到 “/v1/myusers/“.任何正則表達式都可以,但是所有的命名組都必須在servicePattern和routePattern中存在。如果servicePattern沒有匹配到一個serviceId,默認的行為會被啟用。在上面的例子中,serviceId”myusers”將會映射到”/myusers/“(沒有發(fā)現(xiàn)版本)這個特性默認是禁用的,而且只用于發(fā)現(xiàn)的服務(wù)。

給所有映射添加前綴,可以設(shè)置 zuul.prefix 一個值,比如/api。這個前綴默認會刪除,在請求跳轉(zhuǎn)之前。(通過 zuul.stripPrefix=false 可以關(guān)閉這個功能)。你也可以在單個服務(wù)中關(guān)閉這個功能, 例如:

application.ymlzuul:routes:users:path: /myusers/**stripPrefix: false

zuul.stripPrefix只使用于使用了zuul.prefix配置情況下。在一個定義好了的 route’s path中不會有任何影響。

在這個例子中,”users”service的請求”/myusers/101”將會跳轉(zhuǎn)到”/myusers/101”。

zuul.routes 實際上綁定到類型為 ZuulProperties 的對象上. 如果你查看這個對象你會發(fā)現(xiàn)一個叫”retryable”的字段, 設(shè)置為”true”會使Ribbon客戶端自動在失敗時重試(如果你需要修改重試參數(shù), 可以使用Ribbon client configuration)

X-Forwarder-Host請求頭默認添加到轉(zhuǎn)發(fā)請求中。設(shè)置zuul.addProxyHeaders=false禁用它。路徑前綴默認被刪除,
到后臺服務(wù)的請求會添加一個 “X-Forwarded-Prefix”(“/myusers”在上面的例子中)。

一個@EnableZuulProxy的應(yīng)用可以作為單機使用如果你設(shè)置了一個默認路由(”/”),例如zuul.route.home: / 會把所有的請求(”/**”)轉(zhuǎn)到home服務(wù)。

如果需要更細粒度的忽略配置,你可以指定特殊的表達式來配置忽略規(guī)則.這些表達式從route location的開始進行匹配,意味著前綴應(yīng)該被包括在匹配表達式中. 忽略表達式影響所有服務(wù)和取代任何路由的特殊配置.

application.ymlzuul:ignoredPatterns: /**/admin/**routes:users: /myusers/**

這個的意思是所有請求, 比如”/myusers/101”的請求會跳轉(zhuǎn)到”users”服務(wù)的”/101”, 但包含”/admin/”的請求將不被處理.

Zuul Http Client

默認的zull的Http clietn現(xiàn)在是Apach HTTP Client,替代了已過期的Ribbon RestClient。想使用RestClient或使用okhttp3.OKHttpClient,可以設(shè)置ribbon.restclient.enable=true或者ribbon.okhttp.enable=true。

Cookies and Sensitive Headers

在同一個系統(tǒng)的多個服務(wù)之間中分享headers是可以的,但是你可能不想把一些敏感headers泄露到下游服務(wù)器。你可以指定一批忽略的headers列表在路由配置中。Cookies扮演了一個特殊的角色, 因為他們很好的在瀏覽器中定義, 而且他們總是被認為是敏感的. 如果代理的客戶端是瀏覽器, 則對于下游服務(wù)來說對用戶, cookies會引起問題, 因為他們都混在一起。(所有下游服務(wù)看起來認為他們來自同一個地方)。

如果你對于你的服務(wù)設(shè)計很細心,比如,如果只有一個下游的服務(wù)設(shè)置了cookies,你可能會讓它從后端服務(wù)一直追溯到前端調(diào)用者,如果你的代理設(shè)置了cookies而且所有你的后端服務(wù)都是同一系統(tǒng)的一部分,它可以很自然的共享(比如使用spring session去聯(lián)系一些共享狀態(tài))。除此之外,任何下游服務(wù)設(shè)置的cookies可以能不會對前端調(diào)用者產(chǎn)生作用。所以建議對不屬于你的域名的部分在routes里將 “Set-Cookie”和“Cookie”添加到敏感headers。 即使是屬于你的域名的路由, 嘗試仔細思考在允許cookies流傳在它們和代理之間意味著什么。

每個路由中的敏感頭部信息配置按照逗號分隔, 例如:

application.ymlzuul:routes:users:path: /myusers/**sensitiveHeaders: Cookie,Set-Cookie,Authorizationurl: https://downstream

敏感headers也支持全局設(shè)置 zuul.sensitiveHeaders. 如果在單個路由中設(shè)置 sensitiveHeaders 會覆蓋全局 sensitiveHeaders 設(shè)置.

注意: 這是sensitiveHeaders 的默認值, 你無需設(shè)置除非你需要不同的配置. 注意. 這是Spring Cloud Netflix 1.1的新功能(在1.0中, 用戶無法直接控制請求頭和所有cookies).

Ignored Headers

除了每個route敏感頭以外, 你可以設(shè)置一個全局的 zuul.ignoredHeaders 在下游相互調(diào)用間去丟棄這些值(包括請求和響應(yīng)). 如果沒有將Spring Security 添加到運行路徑中, 他們默認是空的, 否則他們會被Spring Secuity初始化一批安全頭(例如 緩存相關(guān)). 在這種情況下, 假設(shè)下游服務(wù)也可能添加這些頭信息, 我希望從代理獲取值.

The Routes Endpoint

如果你使用 @EnableZuulProxy 同時引入了Spring Boot Actuator, 你將默認增加一個endpoint, 提供http服務(wù)的 /routes. 一個GET請求將返回路由匹配列表. 一個POST請求將強制刷新已存在的路由.(比如, 在服務(wù)catalog變化的場景中)

注意:路由列表應(yīng)該自動應(yīng)答服務(wù)登記變化, 但是POST是一種強制立即更新的方案.

窒息模式和本地跳轉(zhuǎn)(Strangulation Patterns and Local Forwards)

一個常見的遷移舊應(yīng)用或者舊接口的方式,就是逐步的替換它的實現(xiàn)。 Zuul代理是一種很有用的工具, 因為你可以使用這種方式處理所有客戶端到舊接口的請求. 只是重定向了一些請求到新的接口.

實例配置:

application.ymlzuul:routes:first:path: /first/**url: http://first.example.comsecond:path: /second/**url: forward:/secondthird:path: /third/**url: forward:/3rdlegacy:path: /**url: http://legacy.example.com

在這個例子中,我們替換了 “l(fā)egacy” ,它映射到所有的請求,但是沒有匹配到其他任何一個請求。路徑 /first/* 指向了一個額外的URL. 并且路徑 /second/* 是一個本地跳轉(zhuǎn). 比如, 帶有Spring注解的 @RequestMapping . 路徑 /third/** 也是一個本地跳轉(zhuǎn), 但是屬于一個不同的前綴. (比如 /third/foo 跳轉(zhuǎn)到 /3rd/foo )。

注意:忽略表達式并不是完全的忽略請求, 只是配置這個代理不處理這些請求(所以他們也是跳轉(zhuǎn)執(zhí)行本地處理)。

Uploading Files through Zuul

如果你使用 @EnableZuulProxy , 你可以使用代理路徑上傳文件, 對于小文件可以正常使用. 對于大文件有可選的路徑”/zuul/“繞過Spring DispatcherServlet (避免處理multipart). 比如對于 zuul.routes.customers=/customers/* , 你可以使用 “/zuul/customers/*” 去上傳大文件. Servlet路徑通過 zuul.servletPath 指定. 如果使用Ribbon負載均衡器的代理路由, 在 處理非常大的文件時, 仍然需要提高超時配置. 比如:

application.yml hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000 ribbon:ConnectTimeout: 3000ReadTimeout: 60000

注意: 對于大文件的上傳流, 你應(yīng)該在請求中使用塊編碼. (有些瀏覽器默認不這么做). 比如在命令行中:

$ curl -v -H "Transfer-Encoding: chunked" \ -F "file=@mylarge.iso" localhost:9999/zuul/simple/file

Plain Embedded Zuul

你可以運行一個沒有代理功能的Zuul服務(wù), 或者有選擇的開關(guān)部分代理功能, 如果你使用 @EnableZuulServer (替代 @EnableZuulProxy ). 你添加的任何 ZuulFilter 類型 實體類都會被自動加載, 和使用 @EnableZuulProxy 一樣, 但不會自動加載任何代理過濾器.

在以下例子中, Zuul服務(wù)中的路由仍然是按照 “zuul.routes.*”指定, 但是沒有服務(wù)發(fā)現(xiàn)和代理, 因此”serviceId”和”url”配置會被忽略. 比如:

application.ymlzuul:routes:api: /api/**

匹配所有的 “/api/**” 給Zuul過濾器鏈.

Disable Zuul Filters

在代理和服務(wù)模式下, 對于Spring Cloud, Zuul默認加入了一批 ZuulFilter 類. 查閱 the zuul filters package 去獲取可能開啟的過濾器. 如果你想關(guān)閉其中一個, 可以簡單的設(shè)置 zuul...disable=true . 按照約定, 在 filter 后面的包是Zuul過濾器類. 比如關(guān)閉 org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter , 可設(shè)置zuul.SendResponseFilter.post.disable=true.

通過Sidecar進行多語言支持(Polyglot support with Sidecar)

你是否有多語言的需要使用Eureka,Ribbon和Config server? Spring Cloud Netflix Sidecar 受 Netflix Prana 啟發(fā)。它引入了一個簡單的HTTP API去獲取所有服務(wù)實例的信息(比如host和port)。你也可以通過依賴Eureka的嵌入式Zuul代理器代理服務(wù)調(diào)用。Spring Cloud Config Server以通過host查找或Zuul代理直接訪問。其他語言需要實現(xiàn)一個健康檢查器,Sidecar才可以通知eureka這個額app是上線還是下線狀態(tài)。

引入Sidecar需要org.springframework.cloud and artifact id spring-cloud-netflix-sidecar.

開啟Sidecar, 需要創(chuàng)建一個包含 @EnableSidecar 的Springboot應(yīng)用程序. 這個注解包括了 @EnableCircuitBreaker, @EnableDiscoveryClient 和 @EnableZuulProxy。Run the resulting application on the same host as the non-jvm application.

配置Sidecar, 添加 sidecar.port and sidecar.health-uri 到 application.yml 中. 屬性 sidecar.port 配置非jvm應(yīng)用正在監(jiān)聽的端口. 這樣Sidecar能夠注冊應(yīng)用到 Eureka. sidecar.health-uri 是一個非JVM應(yīng)用程序提供模仿SpringBoot健康檢查接口的可訪問的uri. 它應(yīng)該返回一個json文檔類似如下:

health-uri-document {"status":"UP" }

這個是Sidecar應(yīng)用程序application.yml的列子:

application.yml server:port: 5678 spring:application:name: sidecarsidecar:port: 8000health-uri: http://localhost:8000/health.json

api方法DiscoveryClient.getInstances()的映射是/hosts/{serviceId}。這里是一個 /hosts/customers返回的示例,它返回了兩個實例在不同的hosts。這個API對于非JVM 應(yīng)用程序是可訪問的. (如果sidecar監(jiān)聽在5678端口上) http://localhost:5678/hosts/{serviceId}。

/hosts/customers [{"host": "myhost","port": 9000,"uri": "http://myhost:9000","serviceId": "CUSTOMERS","secure": false},{"host": "myhost2","port": 9000,"uri": "http://myhost2:9000","serviceId": "CUSTOMERS","secure": false} ]

Zuul會自動的為每一個eureka的服務(wù)添加路由映射為/,所以/customers可以訪問到customers服務(wù)。非JVM的應(yīng)用可以通過http://localhost:5678/customers(假設(shè)sidecar監(jiān)聽在5678)。

如果Config Server注冊到Eureka,非JVM的應(yīng)用可以通過Zuul proxy訪問。如果ConfigServer的serviceId是 configserver 而且Sidecar監(jiān)聽在5678端口上, 則它可以通過 http://localhost:5678/configserver 訪問到.

非JVM應(yīng)用可以使用ConfigServer的功能返回YAML文檔. 比如, 調(diào)用 http://sidecar.local.spring.io:5678/configserver/default-master.yml 可以返回如下文檔:

eureka:client:serviceUrl:defaultZone: http://localhost:8761/eureka/password: password info:description: Spring Cloud Samplesurl: https://github.com/spring-cloud-samples

RxJava with Spring MVC

Spring Cloud Netflix引入了Rxjava

RxJava是一個Reactive Extensions的Java VM實現(xiàn):它是一個使用可觀察數(shù)據(jù)流進行異步編程的編程接口,ReactiveX結(jié)合了觀察者模式、迭代器模式和函數(shù)式編程的精華,與異步數(shù)據(jù)流交互的編程范式。

Spring Cloud Netflix提供并支持從Spring MVC Controllers返回rx.Single對象. 它還支持使用 rx.Observable 對象,可觀察的對象為 Server-sent events (SSE). 如果你的內(nèi)部api已經(jīng)使用RxJava這會非常的方便(可以查看spring-cloud-feign-hystrix為例)。

這里有一些使用rx.Single的列子:

@RequestMapping(method = RequestMethod.GET, value = "/single") public Single<String> single() {return Single.just("single value"); }@RequestMapping(method = RequestMethod.GET, value = "/singleWithResponse") public ResponseEntity<Single<String>> singleWithResponse() {return new ResponseEntity<>(Single.just("single value"),HttpStatus.NOT_FOUND); }@RequestMapping(method = RequestMethod.GET, value = "/singleCreatedWithResponse") public Single<ResponseEntity<String>> singleOuterWithResponse() {return Single.just(new ResponseEntity<>("single value", HttpStatus.CREATED)); }@RequestMapping(method = RequestMethod.GET, value = "/throw") public Single<Object> error() {return Single.error(new RuntimeException("Unexpected")); }

如果你使用 Observable, 而不Single, 你可以使用.toSingle() 或 .toList().toSingle(). 下面是些例子:

@RequestMapping(method = RequestMethod.GET, value = "/single") public Single<String> single() {return Observable.just("single value").toSingle(); }@RequestMapping(method = RequestMethod.GET, value = "/multiple") public Single<List<String>> multiple() {return Observable.just("multiple", "values").toList().toSingle(); }@RequestMapping(method = RequestMethod.GET, value = "/responseWithObservable") public ResponseEntity<Single<String>> responseWithObservable() {Observable<String> observable = Observable.just("single value");HttpHeaders headers = new HttpHeaders();headers.setContentType(APPLICATION_JSON_UTF8);return new ResponseEntity<>(observable.toSingle(), headers, HttpStatus.CREATED); }@RequestMapping(method = RequestMethod.GET, value = "/timeout") public Observable<String> timeout() {return Observable.timer(1, TimeUnit.MINUTES).map(new Func1<Long, String>() {@Overridepublic String call(Long aLong) {return "single value";}}); }

如果你有一個流端點和客戶端,SSE可能是一個選項。使用 RxResponse.sse()將rx.Observable轉(zhuǎn)換到Spring 的SseEmitter. 以下是一些例子:

@RequestMapping(method = RequestMethod.GET, value = "/sse") public SseEmitter single() {return RxResponse.sse(Observable.just("single value")); }@RequestMapping(method = RequestMethod.GET, value = "/messages") public SseEmitter messages() {return RxResponse.sse(Observable.just("message 1", "message 2", "message 3")); }@RequestMapping(method = RequestMethod.GET, value = "/events") public SseEmitter event() {return RxResponse.sse(APPLICATION_JSON_UTF8,Observable.just(new EventDto("Spring io", getDate(2016, 5, 19)),new EventDto("SpringOnePlatform", getDate(2016, 8, 1)))); }

Metrics: Spectator, Servo, and Atlas

什么鬼?以后再說。。。。。

總結(jié)

以上是生活随笔為你收集整理的Spring Cloud Netflix中文文档翻译笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

亚洲成人免费在线 | 中文字幕在线电影 | 国产99色| 麻豆高清免费国产一区 | 国产精品99蜜臀久久不卡二区 | 日韩精品三区四区 | 黄色com| 亚洲v欧美v国产v在线观看 | 亚洲精品456在线播放 | 日韩av中文字幕在线免费观看 | 日韩免费av网址 | 久久久免费播放 | 少妇性色午夜淫片aaaze | 久久久久久久久久久国产精品 | 国产主播大尺度精品福利免费 | 亚洲闷骚少妇在线观看网站 | 国产在线视频资源 | 国产视频综合在线 | 国产美女在线免费观看 | jizz999| 久久久久久97三级 | www99精品| 日韩精品一卡 | 亚洲精品乱码久久 | 91看国产| 四虎在线影视 | 在线日韩三级 | 中文字幕亚洲精品在线观看 | 欧美日韩国内在线 | 日韩a欧美 | 亚洲国产中文字幕 | 国产精品日韩在线观看 | 97av在线| 色婷婷久久久综合中文字幕 | 欧美午夜a | 国产aaa大片 | 欧美少妇xx | 国产黑丝一区二区 | 在线观看黄a| 国产专区日韩专区 | 九九亚洲视频 | 91亚洲精品乱码久久久久久蜜桃 | 国产一区二区三区网站 | 免费中午字幕无吗 | 欧美在线视频一区二区 | 九九视频网| 亚洲精品在线视频播放 | 在线看成人av | 精品免费观看 | 男女视频91 | 中文字幕乱偷在线 | 国产精品白浆视频 | 婷婷播播网| 国产精品a级 | 亚洲精品电影在线 | 视频在线亚洲 | 99热在线网站 | www.97视频 | 色诱亚洲精品久久久久久 | 亚洲精品乱码久久久久久蜜桃不爽 | 久久久资源网 | 天天曰夜夜操 | 国产午夜亚洲精品 | 91伊人影院 | 中文字幕 成人 | 一区二区三区四区五区六区 | 一区二区三区在线不卡 | 国产精品一区二区在线免费观看 | 99久久精品免费一区 | 中文字幕视频观看 | 免费av大片 | 亚州精品国产 | 人人搞人人搞 | 999亚洲国产996395 | 免费观看版 | 久久99久久久久久 | 亚洲精品乱码久久久久久久久久 | 麻豆视频大全 | 国产黄a三级三级三级三级三级 | 国产裸体无遮挡 | 麻豆精品视频在线观看免费 | 亚洲综合色丁香婷婷六月图片 | 亚洲成人午夜在线 | 欧美日韩中文字幕在线视频 | 国产精品人人做人人爽人人添 | 久久久久国产精品一区 | 中文字幕你懂的 | 成人性生爱a∨ | 国产在线精品一区 | 亚洲综合激情网 | 久久免费国产电影 | 菠萝菠萝蜜在线播放 | 黄色小说免费在线观看 | 99精品视频免费全部在线 | 丁五月婷婷 | 婷婷综合影院 | 亚洲www天堂com | 成人av免费在线观看 | 国产精品高清免费在线观看 | 黄色精品久久 | 美女一级毛片视频 | 中文字幕永久 | 美女视频免费精品 | 久久精品视频国产 | 91在线视频免费播放 | 96精品视频 | 欧美日本三级 | 亚洲一区美女视频在线观看免费 | 亚洲综合在线五月 | 国产精品va| 国产一级在线看 | 日本在线观看一区二区三区 | 免费在线观看不卡av | 精品国产成人 | 久久99国产精品自在自在app | 亚洲欧美成人网 | 成人免费在线播放 | 亚洲天堂网在线视频 | 人人看人人爱 | 色噜噜狠狠色综合中国 | 911免费视频| 91福利小视频 | 久久这里有精品 | 国内小视频| 免费网站黄 | 午夜精品视频免费在线观看 | 日日干天夜夜 | 国产一区在线免费观看 | 国产高清黄色 | 欧美精品中文字幕亚洲专区 | 久久综合九色综合久久久精品综合 | 日日夜夜天天操 | 日本中文字幕网址 | 91av电影在线 | 国产一二三在线视频 | 黄色成年片 | 久久狠狠亚洲综合 | 欧美激情精品久久久久久免费 | 西西44人体做爰大胆视频 | 午夜性福利 | 日韩电影中文,亚洲精品乱码 | 伊人久在线 | 999久久国产 | 最近高清中文字幕在线国语5 | 欧美国产一区在线 | 亚洲伊人天堂 | 天天干天天干天天干天天干天天干天天干 | 成人国产精品久久久春色 | 亚洲一区二区麻豆 | 中文字幕字幕中文 | 久黄色| 狠狠狠狠狠狠狠狠 | 插插插色综合 | 97av免费视频 | av久久久 | 国产精品欧美一区二区 | 欧美性生活一级片 | 91超级碰碰| 亚洲成a人片77777kkkk1在线观看 | 99c视频在线| 国产一级精品绿帽视频 | 午夜狠狠干 | 国产裸体永久免费视频网站 | 国产亚洲免费的视频看 | 9797在线看片亚洲精品 | 麻花豆传媒mv在线观看 | 国产在线久久久 | 18女毛片 | 黄色软件视频大全免费下载 | 一区二区 精品 | 久久激情网站 | 天天干天天干天天色 | 精品久久久久久久久久岛国gif | 久久婷亚洲五月一区天天躁 | 久久人人精品 | 日韩欧美国产成人 | 亚州av网站大全 | 97国产一区二区 | 亚洲成av人片在线观看www | 国产在线精品一区二区 | 一区二区电影在线观看 | 亚洲午夜久久久久 | 激情综合亚洲精品 | 一区二区三区在线观看免费 | 免费网站观看www在线观看 | 亚州五月| 久草五月 | 99国产精品免费网站 | 日日干激情五月 | 国产成人久久精品77777综合 | 顶级bbw搡bbbb搡bbbb | 久久国产精品一二三区 | 在线不卡的av | 深爱激情五月婷婷 | av中文字幕网站 | 99免费观看视频 | 四虎国产精品免费观看视频优播 | 亚洲国产中文字幕在线观看 | 成人少妇影院yyyy | 久草精品在线播放 | 国产成人精品区 | 99精品久久久 | av免费看网站 | 日本中文字幕在线视频 | 天天爱av导航 | 久草在线免费资源 | 精品国自产在线观看 | 久久久国产精品亚洲一区 | www欧美xxxx| 激情视频91 | 中文在线www| 97视频资源 | 亚洲日本一区二区在线 | 欧美热久久 | 精品国产一区二区三区久久久蜜月 | 国产精品粉嫩 | 精品极品在线 | 九九热在线观看 | 欧美片一区二区三区 | 国产精品午夜久久 | 日韩最新在线视频 | 狠狠久久 | 一区久久久 | 97偷拍视频 | 欧美日韩国产在线精品 | 一本一本久久a久久精品综合小说 | 99视频在线精品免费观看2 | 狠狠狠干狠狠 | 久久久久久久电影 | 超碰国产人人 | 亚洲国产日韩一区 | 日日夜夜亚洲 | 日韩二区在线观看 | 国产视频在线免费观看 | 91在线超碰 | 一本一本久久a久久精品综合妖精 | 不卡的av电影在线观看 | 日韩精品无码一区二区三区 | 久久精品亚洲一区二区三区观看模式 | 超碰人人舔 | 激情丁香在线 | 国产精品99久久久 | 97视频在线观看网址 | 久久精品麻豆 | 特级黄录像视频 | 五月婷婷激情网 | 亚洲精品观看 | av在线观 | 狠狠狠色 | 欧美99热 | 综合在线观看 | 亚洲国产精品成人av | 人人插超碰 | 亚洲成人免费 | 国产精品久久中文字幕 | 天天摸天天操天天爽 | 久久国产精品99久久人人澡 | 欧洲精品码一区二区三区免费看 | 激情五月播播久久久精品 | av片无限看 | 在线观看完整版免费 | 激情丁香久久 | 久久免费看a级毛毛片 | 在线黄色国产电影 | 亚洲精品玖玖玖av在线看 | 精品999久久久 | 日本少妇高清做爰视频 | 免费国产黄线在线观看视频 | 亚洲精品久久久久中文字幕二区 | 免费av片在线 | 亚洲国产精品一区二区久久,亚洲午夜 | 日韩视频中文 | 69亚洲精品| 久久精品免费电影 | 精品久久亚洲 | 精品少妇一区二区三区在线 | 欧美日韩不卡一区二区三区 | 激情www | 欧美日韩国产一区 | 性色xxxxhd | 人人看人人草 | 在线观看网站黄 | 日本成址在线观看 | av网站大全免费 | 超碰人人av | 国产精品久久久久免费 | 国产亚洲高清视频 | 日韩一区二区三区不卡 | 久久免费在线 | 天堂av色婷婷一区二区三区 | 婷婷丁香在线视频 | 免费日韩精品 | 97精品视频在线播放 | 黄色一级大片在线免费看国产一 | 在线免费av网站 | 精品视频在线看 | 亚洲国产一二三 | 欧美福利视频一区 | 99爱视频在线观看 | 欧洲亚洲国产视频 | 色视频在线免费观看 | 在线观看日韩精品 | 就操操久久 | 色a在线观看 | 日韩免费av片| 免费麻豆网站 | 中文字幕资源网 | 在线观看不卡视频 | 久久狠狠一本精品综合网 | 国产不卡一二三区 | 天天干天天操av | 久久久亚洲成人 | 国产一级免费视频 | 亚洲一级久久 | 福利视频入口 | 欧美视频www | 国产福利网站 | 欧美色图亚洲图片 | 免费看的黄色录像 | 欧美日韩中字 | 91亚洲精品乱码久久久久久蜜桃 | 亚洲精品国产成人 | 欧美夫妻生活视频 | 久精品视频 | 国产精品久久影院 | av电影久久 | 91日韩免费| 看片网站黄色 | 国产精品免费视频一区二区 | 精品亚洲一区二区三区 | 丁香视频全集免费观看 | 蜜桃av人人夜夜澡人人爽 | 天天色天天干天天 | 最新在线你懂的 | 久久精品99国产国产 | 亚洲最大av| 一区二区三区四区免费视频 | 人人要人人澡人人爽人人dvd | 一区 二区 精品 | 91精品视频在线看 | 亚洲成年人免费网站 | 青青五月天 | 国产99精品在线观看 | 一区二区精 | 免费的国产精品 | 操操操操网 | 日韩一区二区三区视频在线 | 97超碰免费在线观看 | 免费无遮挡动漫网站 | 高清不卡一区二区在线 | 欧美成人视 | 久久免费视频这里只有精品 | 在线观看免费黄色 | 91视频电影 | 五月婷婷丁香网 | 日韩欧美电影网 | 日韩激情中文字幕 | www.福利视频 | 午夜精品电影一区二区在线 | 九九在线国产视频 | 人人讲下载 | 五月天婷婷在线视频 | 成人久久久久久久久久 | 五月婷婷操 | 麻豆视频国产精品 | 特级片免费看 | 免费高清影视 | 91片黄在线观看 | 免费又黄又爽的视频 | 精品人人人人 | 国产精品2018 | 国产精品一区二区三区久久久 | 欧美国产日韩一区 | avav99| 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 91精品啪在线观看国产81旧版 | 黄色毛片一级 | 日日夜夜精品网站 | 欧美性猛片 | 日韩高清在线一区 | 91视频首页 | 久久9精品| 黄色三级免费片 | 97超碰资源站 | 日本大片免费观看在线 | 日韩电影在线观看一区二区三区 | 97在线精品国自产拍中文 | 免费看污在线观看 | 色婷婷一区 | 99久久精品一区二区成人 | 99超碰在线播放 | 中文国产成人精品久久一 | 天天要夜夜操 | 色中色综合 | 亚洲最大在线视频 | 99免费在线视频观看 | 超碰人人舔 | 国产成人精品av | 99视频在线精品免费观看2 | 欧美伦理一区二区三区 | 91在线中字 | 五月婷社区 | 一级a性色生活片久久毛片波多野 | 激情深爱 | 久久高清免费 | 午夜色大片在线观看 | 18av在线视频 | 国产剧情在线一区 | 国产成人精品女人久久久 | 深爱激情五月综合 | 国产在线国产 | 九色91福利 | 精品久久久久国产 | 福利网在线 | 国产成人精品亚洲日本在线观看 | 成人黄在线观看 | 色老板在线 | 亚洲一区二区三区四区在线视频 | 天天爱天天操 | avwww在线 | 日本久久精品视频 | 91伊人| 国产综合精品一区二区三区 | 四虎精品成人免费网站 | 丁香激情视频 | 日韩在线视频一区 | 久久天天躁夜夜躁狠狠85麻豆 | 九九九热精品免费视频观看 | 国产精品嫩草影院99网站 | 中文字幕在线有码 | 狠狠操电影网 | 精品久久亚洲 | 欧美福利网站 | 国产成人精品日本亚洲999 | 中文字幕在线播放视频 | 伊人宗合网 | 欧美精彩视频在线观看 | 免费h精品视频在线播放 | 国产精品久久久久久久久免费 | 中国成人一区 | 国产原厂视频在线观看 | 91在线操 | 午夜在线观看 | 成在线播放| 91成人小视频 | 亚州国产精品视频 | 中文字幕在线高清 | 九色精品免费永久在线 | av丝袜制服 | 亚洲精品视频在线观看网站 | 国产精品嫩草影视久久久 | 丁香婷婷在线 | 国产一区二区精品 | 成人v| 蜜桃麻豆www久久囤产精品 | 91在线观看黄 | 久久免视频| 亚洲爱视频 | 日日干美女 | 香蕉成人在线视频 | 亚洲黄色在线 | 日本黄色片一区二区 | 国产欧美在线一区二区三区 | 成人av免费播放 | 国语精品视频 | 色在线免费视频 | 黄色官网在线观看 | 99久久久国产免费 | 国产黄大片 | 国产日韩欧美视频在线观看 | 天天操天天舔天天爽 | 国产精品中文在线 | 91视频高清 | 日韩精品不卡在线 | 国内久久精品视频 | 91视频 - x99av | 91视频免费看片 | 欧美国产视频在线 | 国产做a爱一级久久 | 欧美va电影 | 2021av在线 | 日日日爽爽爽 | 国内精品久久久久久久 | 免费看黄色毛片 | aⅴ精品av导航 | 91精品视频免费在线观看 | 亚洲一区免费在线 | 久久69精品久久久久久久电影好 | 色婷婷av一区二 | 一区在线播放 | 国产成人福利片 | 91人人爽久久涩噜噜噜 | 亚洲免费在线观看视频 | 亚洲无毛专区 | 天天干,天天插 | avlulu久久精品| 91麻豆精品91久久久久同性 | 久久综合色一综合色88 | 黄色一级免费 | 五月婷婷色丁香 | 天天干夜夜干 | 五月婷婷,六月丁香 | 91精品综合在线观看 | 91看片成人 | 亚洲在线激情 | 奇米网8888 | 久久亚洲成人网 | 久久久久综合 | 日本黄色免费观看 | 美腿丝袜av| 成人app在线播放 | 成人h在线观看 | 久久精品一区二区三区四区 | 丰满少妇在线观看资源站 | 精品婷婷| 日韩精品一区二区在线观看视频 | 午夜电影一区 | 亚洲区精品视频 | 蜜臀av性久久久久蜜臀av | 国产亚洲精品综合一区91 | 91精品在线播放 | 久久五月婷婷丁香社区 | 国产在线免费观看 | 免费激情在线电影 | 国产99久久| 91片黄在线观 | 国产精品porn | 精品久久久久久久久亚洲 | 99热国产在线| 99久热在线精品视频成人一区 | 精品你懂的 | 国产亚洲精品成人av久久ww | 激情网站免费观看 | 91黄色在线观看 | 五月激情久久 | 久久超级碰视频 | 免费在线色电影 | 奇米影视777四色米奇影院 | 美女黄频 | 激情婷婷久久 | 欧美久久久久久久久久 | 91精品国产综合久久福利 | 日韩美av在线 | 97超视频免费观看 | 在线观看国产永久免费视频 | 欧美射射射| 美女国内精品自产拍在线播放 | 国产精品视频大全 | 日韩激情视频在线观看 | 国产黄色精品在线 | 色婷婷亚洲 | www操操操 | 久草资源在线 | 99r在线视频 | 一级片视频免费观看 | 四虎在线免费观看视频 | 精品福利视频在线观看 | 日日操夜 | 最近中文国产在线视频 | 欧美激情视频一区二区三区 | 97超碰资源总站 | 很黄很污的视频网站 | 免费久久精品视频 | 成人福利在线播放 | 亚洲精品国产精品99久久 | 欧美一二区在线 | 97手机电影网 | 中文字幕国语官网在线视频 | 亚洲成av人片在线观看无 | 日韩亚洲欧美中文字幕 | 色开心| 在线观看av小说 | 日韩69视频| 91视频啊啊啊 | 日韩精品一区二区三区电影 | 国产日产精品久久久久快鸭 | 国产精品破处视频 | 五月婷婷在线观看 | 欧美日韩视频一区二区 | 一级片免费观看 | 国产高清在线永久 | 日韩欧美在线不卡 | 中文字幕在线影院 | 婷婷久久一区 | 亚洲国产精久久久久久久 | 一级一片免费看 | 亚洲国产日韩在线 | 婷婷深爱网 | 91在线视频免费91 | 日韩欧美中文 | 成年人黄色免费看 | 一区二区 不卡 | 在线a人v观看视频 | 一区二区三区四区五区在线视频 | 久久精品黄 | 亚洲国产99 | 亚洲黄色网络 | 国产精品白丝jk白祙 | 日日操日日插 | 欧美三级在线播放 | 色婷婷99 | 亚洲国产资源 | 国产麻豆精品久久一二三 | 成人毛片a | 国产又粗又猛又黄 | 亚州免费视频 | 天天噜天天色 | 在线看国产视频 | 99久久精品网 | 91精品视频免费观看 | 天天天干天天天操 | 五月婷婷久| 天天综合色天天综合 | 在线看国产精品 | 91丨九色丨高潮丰满 | 99 色 | 亚洲精品综合一二三区在线观看 | 在线观看免费一区 | 久久综合久久综合这里只有精品 | 在线亚洲欧美视频 | 国产精品成人久久久 | 精品成人a区在线观看 | 日韩av中文字幕在线免费观看 | 亚洲精品免费在线观看视频 | 伊人久操| 在线免费av网 | 日韩一级电影在线观看 | 亚洲精品日韩在线观看 | 在线观看911视频 | 亚洲高清精品在线 | 欧美精品二 | 精品国产一区二区三区日日嗨 | 日韩专区在线观看 | 天天插天天狠天天透 | 国产原创av片 | 欧美孕妇视频 | 黄色亚洲片 | 久99久在线 | 久久天天躁夜夜躁狠狠躁2022 | 狠狠色丁香久久婷婷综合五月 | 一区二区视频欧美 | 日韩精品久久久久久中文字幕8 | 亚洲精品视频在线免费播放 | 一区二区三高清 | 91精选在线 | 操一草| 国产在线观看免费av | 一区二区亚洲精品 | 精品视频在线看 | 久久精品亚洲精品国产欧美 | 亚洲精品66 | 波多野结衣视频一区二区 | 日本黄区免费视频观看 | 超碰97在线资源站 | 亚洲人人射 | a视频在线 | 久久精品欧美一 | 在线观看国产亚洲 | 人人爽人人爽人人爽人人爽 | 免费观看v片在线观看 | 欧美作爱视频 | 黄色免费观看 | 国产午夜精品视频 | 成人网在线免费视频 | 射综合网 | 婷婷色婷婷| 久热免费在线 | 黄色影院在线播放 | 久久不卡免费视频 | 伊人五月 | www.香蕉视频| 国产手机在线观看视频 | 91精品久久久久久久99蜜桃 | 亚洲国产精品传媒在线观看 | 99亚洲国产精品 | 国产精品一区二区免费视频 | 丝袜制服天堂 | 国产成人精品免高潮在线观看 | 亚洲精品视频在线免费播放 | 麻豆极品 | 国产成人久久久久 | 国产青草视频在线观看 | 日韩成人在线免费观看 | 日韩电影中文字幕 | 麻豆视频免费入口 | 97在线资源 | 欧美韩国日本在线观看 | 91成人蝌蚪| 国产精品手机在线播放 | 丁香色婷 | 亚洲精品国产品国语在线 | 欧美专区日韩专区 | 久久亚洲综合国产精品99麻豆的功能介绍 | 蜜臀久久99精品久久久无需会员 | 极品久久久| 久久精品精品 | 国产小视频免费在线网址 | 日本久久免费电影 | 九七视频在线观看 | 亚洲.www | 日韩av午夜在线观看 | 狠狠做六月爱婷婷综合aⅴ 日本高清免费中文字幕 | 91天堂在线观看 | 国产资源中文字幕 | 超级碰碰碰免费视频 | 欧美日韩在线视频一区二区 | 99性视频 | av免费观看在线 | 欧美日韩国产一区二区三区 | 狠狠狠狠狠狠干 | 久久国产精品视频免费看 | 97国产在线视频 | 国产精品免费久久久 | 奇米影视777四色米奇影院 | 久久人人爽爽人人爽人人片av | 久草com | 国内精品久久久久久久久久久 | 在线视频18在线视频4k | 91高清免费观看 | 夜夜干夜夜 | 99久久精品久久久久久动态片 | 国产一区不卡在线 | 成年人免费观看国产 | 日本丶国产丶欧美色综合 | 国产美女网 | 欧美九九九 | 狠狠操狠狠 | 97国产一区二区 | 国产精品久久三 | 狠狠88综合久久久久综合网 | 亚洲成成品网站 | 97超碰中文字幕 | 天天爽天天摸 | 国产精品视频在线看 | 开心激情综合网 | 国产成人免费观看 | 97超级碰碰 | 日韩精品不卡在线 | 久久麻豆精品 | 亚洲激情影院 | 国产在线观看高清视频 | 国产日韩欧美在线观看视频 | 九九视频在线 | 综合网天天射 | 天天色天天草天天射 | 婷婷深爱网 | 久久第四色 | 国产成人a v电影 | 国产国语在线 | 黄色www| 日韩免费电影在线观看 | 精品欧美小视频在线观看 | 黄色的网站免费看 | 人人爽人人爽人人片av | 国产精品自在线 | 97碰视频| 欧美色图88 | 精品9999| 日韩美精品视频 | 黄色免费av | 中文字幕第一页在线播放 | 六月丁香婷婷在线 | 色天天中文 | 天天操天天射天天插 | 97精品在线观看 | 特黄免费av | 日韩在线免费小视频 | 国产精品久久久久久一区二区 | www久| 国产精品视频久久久 | 97成人资源 | 久久99精品久久只有精品 | 日本中文字幕在线免费观看 | 天天射天天舔天天干 | 精品xxx | 2021国产精品视频 | 狠狠干.com | 毛片无卡免费无播放器 | 国产精品毛片久久久久久 | 手机成人免费视频 | 九九九九免费视频 | 在线看片中文字幕 | 丁香导航 | 国产高清av免费在线观看 | 中文字幕乱码在线播放 | 日韩精品专区在线影院重磅 | 亚洲国产小视频在线观看 | 97超碰免费在线观看 | 91精品人成在线观看 | 一区二区三区高清在线观看 | 日韩经典一区二区三区 | 日日爽 | a午夜电影 | 波多野结衣在线播放视频 | 九九激情视频 | www.福利 | 色偷偷人人澡久久超碰69 | 日日夜夜添 | 九九免费在线观看 | 日韩91在线 | 天天看天天干天天操 | 日韩欧美国产成人 | 国产成人精品区 | 在线免费观看的av网站 | 国产成人在线精品 | 国产视频导航 | av在线免费播放网站 | 综合色天天 | 麻豆久久久久久久 | 久久免费黄色 | 在线电影中文字幕 | 九九九热 | 中文字幕韩在线第一页 | 日韩理论在线视频 | 国产精品毛片久久久久久久 | 激情五月在线观看 | 日韩免费一区二区在线观看 | 成人久久久久久久久久 | 韩国精品一区二区三区六区色诱 | 六月丁香激情网 | 午夜国产在线 | 国产中文字幕第一页 | 国产精品黄网站在线观看 | 久久久久久高潮国产精品视 | 日韩欧三级 | 日韩电影中文字幕在线 | 久久一区二区三区超碰国产精品 | 丁香六月伊人 | 亚洲激情六月 | 久久精品国产成人精品 | 91精品一区国产高清在线gif | 97视频总站 | 欧美精品亚洲精品日韩精品 | 蜜臀久久99静品久久久久久 | 在线视频在线观看 | 亚洲午夜精品电影 | 国产高清免费 | 综合久久久久 | 久久精品99国产精品日本 | 日本最新高清不卡中文字幕 | 可以免费看av| 色婷在线 | 久草网站在线观看 | 色狠狠久久av五月综合 | 欧美日韩在线观看一区二区 | 国产在线观看网站 | 日韩中文字幕免费在线观看 | 欧美aaa一级| 国外调教视频网站 | 一区二区视频在线看 | 亚洲精品在线观看视频 | 国产成人久久77777精品 | 91免费在线视频 | 亚洲一二三在线 | 天天艹天天 | 成人免费视频播放 | 亚洲天堂精品 | 最新的av网站 | 精品国产乱码一区二区三区在线 | 亚洲欧洲精品久久 | 国产在线国偷精品产拍 | 91丨九色丨蝌蚪丰满 | 日韩高清国产精品 | 久久久久日本精品一区二区三区 | 国产成人精品综合久久久 | 成人黄色av免费在线观看 | 91在线精品播放 | 久久精品一区二区三区四区 | av中文字幕日韩 | 色瓜 | 亚洲成免费 | 最新av网址在线观看 | 成人久久国产 | 色网站中文字幕 | 97操操操| 六月色丁| 成人三级网站在线观看 | 一区二区三区日韩视频在线观看 | 在线亚洲日本 | 欧美疯狂性受xxxxx另类 | 久久久国产精品一区二区三区 | 欧美analxxxx | 男女免费av| 国产精品久久久av久久久 | 九九日九九操 | 亚洲综合五月天 | 国产成人精品三级 | 免费日韩视频 | 国产成人福利在线 | 91秒拍国产福利一区 | 天天插视频 | 国产日韩欧美自拍 | 精品99在线视频 | 欧美激情精品久久久久久免费 | 91精品1区2区 | 国产不卡在线观看 | 久久免费一 | 狠狠干夜夜操天天爽 | 992tv在线 | 人人插超碰 | 亚洲专区在线播放 | 国产精品久久久久高潮 | 午夜性福利 | 国产精品网红福利 | 久久久国产99久久国产一 | 精品国产一区二区三区免费 | 欧美日高清视频 | 国产专区精品 | 成人aⅴ视频| 国产成人性色生活片 | 久久不卡日韩美女 | 中文字幕在线播放日韩 | 丝袜美腿亚洲综合 | 国产精品国产毛片 | 国产97色| 亚洲va欧美va人人爽 | 最新av免费在线 | 在线一区二区三区 | 天天摸天天弄 | 国产精品久久久久久久久久久久冷 | 免费在线观看国产精品 | 国产精品白浆视频 | 嫩草av影院 | 午夜精品久久久 | 国产精品视频不卡 | 91黄色在线视频 | 98超碰在线 | 丁香花在线观看免费完整版视频 | 99精品在线直播 | 久久精选 | 国产精品一区二区视频 | 日韩精品一区二区在线 | 国产精品人成电影在线观看 | 欧美色就是色 | 91av综合| 99精品国产在热久久下载 | 亚洲最大的av网站 | 一区二区三区国产精品 | 欧美精品在线视频 | 日韩av电影手机在线观看 | 99精品区 | 97色婷婷人人爽人人 | 亚洲综合情 | 欧美日韩久久不卡 | 久久午夜剧场 | 在线免费观看亚洲视频 | 91在线观看视频网站 | 日韩av一卡二卡三卡 | 欧美精品亚洲精品日韩精品 | 在线观看精品视频 | 国产一级片直播 | 99精品免费在线观看 | 久草免费在线观看视频 | 欧美日韩精品综合 | 久久久久久久国产精品视频 | 欧美日韩在线免费观看视频 | 在线观看蜜桃视频 | 欧美一级黄色网 | 黄色一级大片在线免费看国产一 | 深爱激情久久 | 欧美日韩裸体免费视频 | 婷婷六月综合网 | 久久av免费观看 | 久久国产热视频 | 美女中文字幕 | 亚洲国产精品成人女人久久 | 九精品 | 精品999 | 国产高清成人av | 国产91精品高清一区二区三区 | 国产在线视频在线观看 | 四虎免费在线观看 | 国产精品嫩草55av | 9999精品视频| 中文字幕精品在线 | 一区二区三区免费播放 | 91精品免费在线视频 | 免费在线激情视频 | 搡bbbb搡bbb视频| 亚洲精品伦理在线 | 精品久久亚洲 | 欧美午夜精品久久久久 | 国产精品第一页在线观看 | 999久久久久久久久6666 | 欧美日在线观看 | 激情网站免费观看 | 在线观看午夜av | 国产美女视频网站 | 美女黄频| 人人爱爱人人 | 一区二区三区四区在线 | 在线天堂日本 | 国内精品免费久久影院 | 久久99视频 | 国产福利91精品张津瑜 | 激情五月视频 | www.黄色在线 | 九九免费在线观看 |