|
微服務(wù)的其中一個(gè)特點(diǎn)就是有許許多的粒度?。üδ軉我?,比如用戶管理,短信發(fā)送管理,郵件發(fā)送管理,文件管理等)、能獨(dú)立部署、擴(kuò)展、運(yùn)行的小應(yīng)用,可以稱為api,也就是服務(wù)提供者。api之間可以相互調(diào)用,但更多的是供app調(diào)用,比如學(xué)生管理系統(tǒng),它是面向用戶的,是許許多多功能的集合體,它需要調(diào)用許多api完成業(yè)務(wù)功能,所以這學(xué)生管理系統(tǒng)可以稱為app。 eureka的作用 傳統(tǒng)的單體應(yīng)用開發(fā),就是將api和app的代碼全部集成在一起,在同一個(gè)進(jìn)程中運(yùn)行,對(duì)應(yīng)java web通俗的說就是全部打包在一個(gè)war中部署在一個(gè)tomcat中運(yùn)行。而微服務(wù)的每個(gè)api,app都擁有自己的進(jìn)程,也就是都有自己的tomcat,某個(gè)api掛了,不影響其他api和app運(yùn)行。 
api是采取restfull風(fēng)格暴漏出去的,所以app(api)調(diào)用api時(shí),采取http://ip:端口這形式進(jìn)行通訊。那么問題來了,如果有很多app都調(diào)用了某個(gè)api,如果api的ip或端口發(fā)生了更改,如果app中對(duì)api的ip和端口等信息是寫在配置文件的,難道要通知每個(gè)app,說這個(gè)api的地址和端口變了,app要進(jìn)行修改重新編譯部署(這是舉例子而已,實(shí)際情況有些企業(yè)對(duì)常量的配置可能寫配置文件,也可能寫數(shù)據(jù)庫(kù))。這太麻煩了,如果api的地址和端口有發(fā)生變化,app能及時(shí)獲知自行變更,那就好了。還有個(gè)弊端,就是api是否掛了,也沒法直觀觀察到。 所以,如果在app和api之間增加個(gè)服務(wù)管理中心,api像服務(wù)管理中心注冊(cè)信息,app從服務(wù)管理中心獲取api的信息,api有個(gè)唯一標(biāo)識(shí),api有變更的時(shí)候通知服務(wù)管理中心,服務(wù)管理中心通知相關(guān)的app或者app定時(shí)從服務(wù)管理中心獲取最新的api信息,同時(shí)服務(wù)管理中心具有很高的穩(wěn)定性、可靠性。 eureka就是為了這樣的一個(gè)服務(wù)管理中心,下面是我根據(jù)自己的理解畫的一張圖。 
下面這張是官方的架構(gòu)圖 
- Application Service 相當(dāng)于服務(wù)提供者/api
- Application Client 相當(dāng)于服務(wù)消費(fèi)者/app
- Make Remote Call,其實(shí)就是實(shí)現(xiàn)服務(wù)的使用/比如httpClient,restTemplate
- us-east-1 Eureka 集群服務(wù)
- us-east-1c、us-east-1d、us-east-1e 就是具體的某個(gè)eureka
Eureka: 1. 是純正的 servlet 應(yīng)用,需構(gòu)建成war包部署
2. 使用了 Jersey 框架實(shí)現(xiàn)自身的 RESTful HTTP接口
3. peer之間的同步與服務(wù)的注冊(cè)全部通過 HTTP 協(xié)議實(shí)現(xiàn)
4. 定時(shí)任務(wù)(發(fā)送心跳、定時(shí)清理過期服務(wù)、節(jié)點(diǎn)同步等)通過 JDK 自帶的 Timer 實(shí)現(xiàn)
5. 內(nèi)存緩存使用Google的guava包實(shí)現(xiàn)
eureka集群搭建 和eureka類似功能的有zookeeper,etcd等。spring boot已經(jīng)集成了eureka,所以我們可以像spring boot那樣搭建環(huán)境,部署運(yùn)行。 我是在window10下使用eclipse學(xué)習(xí)的。 準(zhǔn)備工作。 在修改hosts文件,在最后面加上(位置:C:\Windows\System32\drivers\etc) - 127.0.0.1 01.eureka.server
- 127.0.0.1 02.eureka.server
- 127.0.0.1 03.eureka.server
eclipse下創(chuàng)建個(gè)普通的maven項(xiàng)目eureka-server。 pom.xml - <project xmlns='http://maven./POM/4.0.0' xmlns:xsi='http://www./2001/XMLSchema-instance'
- xsi:schemaLocation='http://maven./POM/4.0.0 http://maven./xsd/maven-4.0.0.xsd'>
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.fei.springcloud</groupId>
- <artifactId>springcloud-eureka-server</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <description>eureka服務(wù)端</description>
-
- <!-- 依賴倉(cāng)庫(kù) 設(shè)置從aliyun倉(cāng)庫(kù)下載 -->
- <repositories>
- <repository>
- <id>alimaven</id>
- <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
- <snapshots>
- <enabled>true</enabled>
- </snapshots>
- <releases>
- <enabled>true</enabled>
- </releases>
- </repository>
- </repositories>
- <!-- 插件依賴倉(cāng)庫(kù) -->
- <pluginRepositories>
- <pluginRepository>
- <id>alimaven</id>
- <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
- <snapshots>
- <enabled>true</enabled>
- </snapshots>
- <releases>
- <enabled>true</enabled>
- </releases>
- </pluginRepository>
- </pluginRepositories>
-
- <properties>
-
- <!-- 文件拷貝時(shí)的編碼 -->
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <!-- 編譯時(shí)的編碼 -->
- <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
-
- <java.version>1.8</java.version>
- <maven.compiler.source>1.8</maven.compiler.source>
- <maven.compiler.target>1.8</maven.compiler.target>
-
- </properties>
-
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>1.5.2.RELEASE</version>
- <relativePath />
-
- </parent>
-
- <dependencies>
-
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-eureka-server</artifactId>
- </dependency>
-
- </dependencies>
-
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-dependencies</artifactId>
- <version>Dalston.RELEASE</version>
- <type>pom</type>
- <scope>import</scope><!-- 這個(gè)不能丟 -->
- </dependency>
-
- </dependencies>
- </dependencyManagement>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- </project>
啟動(dòng)類Application.java - package com.fei.springcloud;
-
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
-
- @EnableEurekaServer
- @SpringBootApplication
- public class Application {
-
- public static void main(String[] args) {
-
- SpringApplication.run(Application.class, args);
- }
- }
注意注解:@EnableEurekaServer,表明這是server服務(wù) 配置文件application.properties
- logging.config=classpath:logback.xml
- logging.path=d:/logs
-
- ##tomcat set###
-
- # eureka的默認(rèn)端口是8761
- server.port=8081
- server.session-timeout=60
- ###########
-
- spring.application.name=eureka-server-01
-
- ####下面2個(gè)一定要false,因?yàn)檫@程序是要作為服務(wù)端,但是jar中存在eureka-client.jar,所以要false,否則啟動(dòng)會(huì)報(bào)錯(cuò)的
- #是否注冊(cè)到eureka
- eureka.client.register-with-eureka=false
- #是否獲取注冊(cè)信息
- eureka.client.fetch-registry=false
-
- #為了便于測(cè)試,取消eureka的保護(hù)模式,如果啟動(dòng)的話,比如api提供者關(guān)閉了,但是eureka仍然保留信息
- eureka.server.enable-self-preservation=false
- #服務(wù)名稱
- eureka.instance.hostname=01.reka
- #eureka的服務(wù)地址,/eureka是固定的
- eureka.client.serviceUrl.defaultZone=http://02.reka:8082/eureka/,http://03.reka:8083/eureka/
注意:eureka.client.serviceUrl.defaultZone的配置,如果是01,則填寫02、03的地址和端口;如果是02,則填寫01、03的地址和端口,也就是說讓01,02,03這3個(gè)eureka服務(wù)能相互間同步數(shù)據(jù),如果是01->02->03->01,則api提供者注冊(cè)信息到01時(shí),01會(huì)同步數(shù)據(jù)到02,但02不會(huì)同步到03,01也不會(huì)同步到03,也就是說03缺數(shù)據(jù)了。看源碼,服務(wù)的注冊(cè)信息不會(huì)被二次傳播,看PeerAwareInstanceRegistryImpl.java 
啟動(dòng)01 eureka,然后修改application.properties,變?yōu)?2 eureka的配置 - logging.config=classpath:logback.xml
- logging.path=d:/logs
-
- ##tomcat set###
-
- # eureka的默認(rèn)端口是8761
- server.port=8082
- server.session-timeout=60
- ###########
-
- spring.application.name=eureka-server-02
-
- ####下面2個(gè)一定要false,因?yàn)檫@程序是要作為服務(wù)端,但是jar中存在eureka-client.jar,所以要false,否則啟動(dòng)會(huì)報(bào)錯(cuò)的
- #是否注冊(cè)到eureka
- eureka.client.register-with-eureka=false
- #是否獲取注冊(cè)信息
- eureka.client.fetch-registry=false
-
- #為了便于測(cè)試,取消eureka的保護(hù)模式,如果啟動(dòng)的話,比如api提供者關(guān)閉了,但是eureka仍然保留信息
- eureka.server.enable-self-preservation=false
- #服務(wù)名稱
- eureka.instance.hostname=02.reka
- #eureka的服務(wù)地址,/eureka是固定的
- eureka.client.serviceUrl.defaultZone=http://01.reka:8081/eureka/,http://03.reka:8083/eureka/
然后執(zhí)行啟動(dòng)類,03也是一樣的操作。 瀏覽器訪問http://01.reka:8081/(或者h(yuǎn)ttp://02.reka:8082/,或者h(yuǎn)ttp://03.reka:8083/)看到 
api提供者 創(chuàng)建個(gè)普通的maven項(xiàng)目eureka-api,該api是個(gè)用戶服務(wù)提供者。采取spring boot開發(fā)模式 
pom.xml - <project xmlns='http://maven./POM/4.0.0' xmlns:xsi='http://www./2001/XMLSchema-instance'
- xsi:schemaLocation='http://maven./POM/4.0.0 http://maven./xsd/maven-4.0.0.xsd'>
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.fei.springcloud</groupId>
- <artifactId>springcloud-eureka-server</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <description>eureka服務(wù)端</description>
-
- <!-- 依賴倉(cāng)庫(kù) 設(shè)置從aliyun倉(cāng)庫(kù)下載 -->
- <repositories>
- <repository>
- <id>alimaven</id>
- <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
- <snapshots>
- <enabled>true</enabled>
- </snapshots>
- <releases>
- <enabled>true</enabled>
- </releases>
- </repository>
- </repositories>
- <!-- 插件依賴倉(cāng)庫(kù) -->
- <pluginRepositories>
- <pluginRepository>
- <id>alimaven</id>
- <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
- <snapshots>
- <enabled>true</enabled>
- </snapshots>
- <releases>
- <enabled>true</enabled>
- </releases>
- </pluginRepository>
- </pluginRepositories>
-
- <properties>
-
- <!-- 文件拷貝時(shí)的編碼 -->
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <!-- 編譯時(shí)的編碼 -->
- <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
-
- <java.version>1.8</java.version>
- <maven.compiler.source>1.8</maven.compiler.source>
- <maven.compiler.target>1.8</maven.compiler.target>
-
- </properties>
-
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>1.5.2.RELEASE</version>
- <relativePath />
-
- </parent>
-
- <dependencies>
-
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-eureka</artifactId>
- </dependency>
-
- </dependencies>
-
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-dependencies</artifactId>
- <version>Dalston.RELEASE</version>
- <type>pom</type>
- <scope>import</scope><!-- 這個(gè)不能丟 -->
- </dependency>
-
- </dependencies>
- </dependencyManagement>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
- </project>
它和eureka 服務(wù)端,有個(gè)依賴是不一樣的。application.properties - logging.config=classpath:logback.xml
- logging.path=d:/logs
-
- ##tomcat set###
-
- # eureka的默認(rèn)端口是8761
- server.port=9081
- server.session-timeout=60
- ###########
-
- spring.application.name=api-user-server
-
- #像eureka服務(wù)注冊(cè)信息時(shí),使用ip地址,默認(rèn)使用hostname
- eureka.instance.preferIpAddress=true
- #服務(wù)的instance-id默認(rèn)默認(rèn)值是${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}} ,
- #也就是機(jī)器主機(jī)名:應(yīng)用名稱:應(yīng)用端口
- eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port}
- #eureka的服務(wù)地址
- eureka.client.serviceUrl.defaultZone=http://01.reka:8081/eureka/
Application.java - package com.fei.springcloud;
-
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
-
- @EnableEurekaClient
- @SpringBootApplication
- public class Application {
-
- public static void main(String[] args) {
-
- SpringApplication.run(Application.class, args);
- }
- }
@EnableEurekaClient,不管是消費(fèi)者還是提供者,對(duì)應(yīng)eureka server來說都是客戶端client寫個(gè)普通的controller,UserProvider.java.提供個(gè)根據(jù)id獲取用戶信息的接口 - package com.fei.springcloud.provider;
-
- import javax.servlet.http.HttpServletRequest;
-
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- @RestController
- @RequestMapping('/user')
- public class UserProvider {
-
- @GetMapping(value='/find/{id}')
- public String find(@PathVariable('id') String id,HttpServletRequest request){
- //實(shí)際項(xiàng)目中,這里可以使用JSONObject,返回json字符串
- //為了便于測(cè)試消費(fèi)者app的負(fù)載均衡,返回服務(wù)端端口
- String s = '張三' ' 服務(wù)端端口:' request.getLocalPort();
-
- return s;
- }
- }
執(zhí)行Application.java,將application.properties的端口修改為9082,再次執(zhí)行 瀏覽器訪問http://01.reka:8081/

Application就是文件中定義的spring.application.name=api-user-server,它會(huì)自動(dòng)轉(zhuǎn)為大寫 app消費(fèi)者 在Spring Cloud Netflix中,使用Ribbon實(shí)現(xiàn)客戶端負(fù)載均衡,使用Feign實(shí)現(xiàn)聲明式HTTP客戶端調(diào)用——即寫得像本地函數(shù)調(diào)用一樣. ribbo負(fù)載均衡的app消費(fèi)者 創(chuàng)建個(gè)普通的maven項(xiàng)目eureka-app-ribbo. 
pom.xml application.properties- logging.config=classpath:logback.xml
- logging.path=d:/logs
-
- ##tomcat set###
-
- # eureka的默認(rèn)端口是8761
- server.port=7081
- server.session-timeout=60
- ###########
-
- spring.application.name=app-user
-
- #像eureka服務(wù)注冊(cè)信息時(shí),使用ip地址,默認(rèn)使用hostname
- eureka.instance.preferIpAddress=true
- #服務(wù)的instance-id默認(rèn)默認(rèn)值是${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}} ,
- #也就是機(jī)器主機(jī)名:應(yīng)用名稱:應(yīng)用端口
- eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port}
- #eureka的服務(wù)地址
- eureka.client.serviceUrl.defaultZone=http://01.reka:8081/eureka/,http://02.reka:8082/eureka/,http://03.reka:8083/eureka/
UserController.java- package com.fei.springcloud.controller;
-
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.ResponseBody;
- import org.springframework.web.client.RestTemplate;
-
- @Controller
- @RequestMapping('/user')
- public class UserController {
-
- @Autowired
- private RestTemplate restTemplate;
-
- @GetMapping(value = '/find')
- @ResponseBody
- public String find() {
- //url中對(duì)應(yīng)api提供者的名稱,全大寫
- String s = restTemplate.getForEntity('http://API-USER-SERVER/user/find/123', String.class).getBody();
- return s;
- }
-
- /**
- * 測(cè)試下外網(wǎng),也就是如果域名是外網(wǎng)的,不在eureka注冊(cè)服務(wù)中的,會(huì)怎樣
- * @return
- */
- @GetMapping(value = '/test')
- @ResponseBody
- public String test() {
- //url中對(duì)應(yīng)api提供者的名稱,全大寫
- return restTemplate.getForEntity('http://www.baidu.com/', String.class).getBody();
- }
- }
使用restTemplate需要自己拼接url 啟動(dòng)類Application.java- package com.fei.springcloud;
-
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.cloud.client.loadbalancer.LoadBalanced;
- import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
- import org.springframework.context.annotation.Bean;
- import org.springframework.web.client.RestTemplate;
-
- @EnableEurekaClient
- @SpringBootApplication
- public class Application {
-
- @Bean //定義REST客戶端,RestTemplate實(shí)例
- @LoadBalanced //開啟負(fù)債均衡的能力
- RestTemplate restTemplate() {
- return new RestTemplate();
- }
-
- public static void main(String[] args) {
-
- SpringApplication.run(Application.class, args);
- }
- }
eureka服務(wù) 瀏覽器訪問http://127.0.0.1:7081/user/find
看到信息“張三 服務(wù)端端口:9081”,刷新瀏覽器看到“張三 服務(wù)端端口:9082”,說明的確是有負(fù)載均衡。 但是訪問外網(wǎng)的時(shí)候,http://127.0.0.1:7081/user/test,也就是域名不在eureka注冊(cè)過的,就不行了。 
以后再研究下如何解決。 feign的app消費(fèi)者 feign可以寫個(gè)接口,加上相關(guān)的注解,調(diào)用的時(shí)候,會(huì)自動(dòng)拼接url,調(diào)用者就像調(diào)用本地接口一樣的操作。 Feign也用到ribbon,當(dāng)你使用@ FeignClient,ribbon自動(dòng)被應(yīng)用。 像ribbo創(chuàng)建個(gè)項(xiàng)目,或者直接在ribbo項(xiàng)目修改都OK。 pom.xml 把ribbo的依賴修改為feign application.properties和上面一樣- logging.config=classpath:logback.xml
- logging.path=d:/logs
-
- ##tomcat set###
-
- # eureka的默認(rèn)端口是8761
- server.port=7081
- server.session-timeout=60
- ###########
-
- spring.application.name=app-user
-
- #像eureka服務(wù)注冊(cè)信息時(shí),使用ip地址,默認(rèn)使用hostname
- eureka.instance.preferIpAddress=true
- #服務(wù)的instance-id默認(rèn)默認(rèn)值是${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}} ,
- #也就是機(jī)器主機(jī)名:應(yīng)用名稱:應(yīng)用端口
- eureka.instance.instance-id=${spring.cloud.client.ipAddress}:${server.port}
- #eureka的服務(wù)地址
- eureka.client.serviceUrl.defaultZone=http://01.reka:8081/eureka/,http://02.reka:8082/eureka/,http://03.reka:8083/eureka/
增加個(gè)UserService.java接口類- package com.fei.springcloud.service;
-
- import org.springframework.cloud.netflix.feign.FeignClient;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.PathVariable;
-
- @FeignClient('API-USER-SERVER')
- public interface UserService {
-
- @GetMapping(value='/user/find/{id}')
- String find(@PathVariable('id') String id);
- }
UserController.java- package com.fei.springcloud.controller;
-
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.ResponseBody;
-
- import com.fei.springcloud.service.UserService;
-
- @Controller
- @RequestMapping('/user')
- public class UserController {
-
- @Autowired
- private UserService userService;
-
- @GetMapping(value = '/find')
- @ResponseBody
- public String find() {
- //url中對(duì)應(yīng)api提供者的名稱,全大寫
- String s = userService.find('123');
- return s;
- }
-
-
- }
瀏覽器訪問http://127.0.0.1:7081/user/find,得到信息“張三 服務(wù)端端口:9081”,刷新,得到“張三 服務(wù)端端口:9082”,Feign也用到ribbon,當(dāng)你使用@ FeignClient,ribbon自動(dòng)被應(yīng)用。所以也會(huì)負(fù)載均衡
ribbo負(fù)載均衡策略選擇
AvailabilityFilteringRule:過濾掉那些因?yàn)橐恢边B接失敗的被標(biāo)記為circuit tripped的后端server,并過濾掉那些高并發(fā)的的后端server(active connections 超過配置的閾值) | 使用一個(gè)AvailabilityPredicate來包含過濾server的邏輯,其實(shí)就就是檢查status里記錄的各個(gè)server的運(yùn)行狀態(tài) RandomRule:隨機(jī)選擇一個(gè)server BestAvailabl:選擇一個(gè)最小的并發(fā)請(qǐng)求的server,逐個(gè)考察Server,如果Server被tripped了,則忽略 RoundRobinRule:roundRobin方式輪詢選擇, 輪詢index,選擇index對(duì)應(yīng)位置的server WeightedResponseTimeRule:根據(jù)響應(yīng)時(shí)間分配一個(gè)weight(權(quán)重),響應(yīng)時(shí)間越長(zhǎng),weight越小,被選中的可能性越低 RetryRule:對(duì)選定的負(fù)載均衡策略機(jī)上重試機(jī)制,在一個(gè)配置時(shí)間段內(nèi)當(dāng)選擇server不成功,則一直嘗試使用subRule的方式選擇一個(gè)可用的server ZoneAvoidanceRule:復(fù)合判斷server所在區(qū)域的性能和server的可用性選擇server ResponseTimeWeightedRule:作用同WeightedResponseTimeRule,二者作用是一樣的,ResponseTimeWeightedRule后來改名為WeightedResponseTimeRule
在app消費(fèi)者的application.properties配置文件中加入 - #ribbo負(fù)載均衡策略配置,默認(rèn)是依次輪詢
- API-USER-SERVER.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
其中API-USER-SERVER是api服務(wù)提供者的服務(wù)名稱,也就是說,可以給每個(gè)不同的api服務(wù)提供者配置不同的復(fù)制均衡策略,驗(yàn)證就不貼圖了
完整的代碼 負(fù)載均衡策略在消費(fèi)端配置的缺點(diǎn) 在上面的例子中,ribbon的負(fù)載均衡是在消費(fèi)端完成的。流程是這樣的:提供者服務(wù)A集群,啟動(dòng)2個(gè)進(jìn)程A1,A2,都注冊(cè)到eureka,app消費(fèi)端根據(jù)api服務(wù)者名稱獲取到A1,A2的具體連接地址,ribbon就對(duì)A1,A2進(jìn)行負(fù)載均衡。 缺點(diǎn): 1) 如果所有的app消費(fèi)端的配置策略不好,導(dǎo)致絕大部分的請(qǐng)求都到A1,那A1的壓力就大了。也就是說負(fù)載策略不是有api提供者所控制的了(這里就不說A1,A2所在的服務(wù)器哪個(gè)性能更好了,因?yàn)槿绻鸻pp/api都是在Docker中運(yùn)行,k8s負(fù)責(zé)資源調(diào)配的話,可以認(rèn)為每個(gè)服務(wù)的進(jìn)程所在的docker配置是一樣的,比如A服務(wù)對(duì)應(yīng)的A1,A2系統(tǒng)環(huán)境是一致的,B服務(wù)對(duì)應(yīng)的B1,B2,B3系統(tǒng)環(huán)境是一致的,只是所對(duì)應(yīng)的宿主機(jī)服務(wù)器估計(jì)不一樣而已)。 2)如果api提供者需要開放給第三方公司的時(shí)候,總不能把A1,A2告訴第三方吧,說我們這A服務(wù)集群了,有A1,A2,你隨意吧。 我們實(shí)際項(xiàng)目中的做法,都是每個(gè)提供者服務(wù)都有自己的nginx管理自己的集群,然后把nginx的域名提供給app消費(fèi)者即可。之所以每個(gè)服務(wù)提供者都有自己的nginx,是因?yàn)閐ocker被k8s管控的時(shí)候,ip都是變化的,需要更新到nginx中。如果A,B都共用一個(gè)nginx,那A重構(gòu)建部署的時(shí)候,A1,A2的ip變化了,需要更新到nginx中去,那如果導(dǎo)致nginx出現(xiàn)問題了,豈不是影響到B的使用了,所以A,B都有自己的nginx。那spring cloud沒有解決方案了嗎?有。spring cloud集成了zuul,zuul服務(wù)網(wǎng)關(guān),不但提供了和nginx一樣的反向代理功能,還提供了負(fù)載均衡、監(jiān)控、過濾等功能,在后面學(xué)習(xí)zuul的時(shí)候,我們?cè)賹W(xué)習(xí)。 
docker k8s實(shí)現(xiàn)的devOps平臺(tái)(paas平臺(tái)),構(gòu)建好鏡像后,部署的時(shí)候,k8s負(fù)責(zé)調(diào)控資源,將docker分配到不同的節(jié)點(diǎn)服務(wù)器,同時(shí)將docker的ip相關(guān)信息更新到nginx。這是自動(dòng)化的,不需要開發(fā)人員手動(dòng)操作docker,nginx配置。 版權(quán)聲明: http://blog.csdn.net/dream_broken/article/details/76148513
|