在分布式環(huán)境中茸俭,需要充分考慮發(fā)生故障的情況,在生產(chǎn)環(huán)境中必須要高可用的部署安皱。
上一篇文章中调鬓,eureka server是單一的服務(wù),所以不需要注冊(cè)自己练俐,但在集群環(huán)境中袖迎,需要eureka server相互注冊(cè)冕臭,所以下面2項(xiàng)要注意了
# 關(guān)閉自己注冊(cè)自己
eureka.client.register-with-eureka=false
# 不需要檢索服務(wù)
eureka.client.fetch-registry=false
在eureka server里增加2個(gè)配置文件:application-peer1腺晾,application-peer2如下
application-peer1.properties 建議使用域名,就要先修改hosts文件辜贵。
spring.application.name=eureka-server
server.port=1111
eureka.instance.hostname=peer1
eureka.client.serviceUrl.defaultZone=http://peer2:1112/eureka/
application-peer2.properties
spring.application.name=eureka-server
server.port=1112
eureka.instance.hostname=peer2
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/
請(qǐng)注意了悯蝉,這2個(gè)配置文件是相互注冊(cè)的,你中有我托慨,我中有你鼻由。
下面啟動(dòng)2個(gè)eureka server:
java -jar eureka-server.jar --spring.profiles.active=peer1
java -jar eureka-server.jar --spring.profiles.active=peer2
啟動(dòng)服務(wù),可以查看控臺(tái):http://peer1:1111/和http://peer2:1112/
可以在
registered-replicas
看到都相互注冊(cè)了,available-replicas
可用分片中可以看到相應(yīng)的節(jié)點(diǎn)蕉世,停止一個(gè)另一個(gè)還可以工作蔼紧,如下圖:關(guān)閉一個(gè)server后,如上圖有一個(gè)DOWN狠轻,若關(guān)閉保護(hù)模式奸例,一會(huì)這個(gè)服務(wù)將會(huì)被清除掉。
若available-replicas沒有相應(yīng)節(jié)點(diǎn)向楼,則是因?yàn)閑ureka.client.register-with-eureka/eureka.client.fetch-registry為false查吊,可以把a(bǔ)pplication.properties中改為true,或在peer配置文件中改為true湖蜕,默認(rèn)就為true逻卖。
上面即實(shí)現(xiàn)了注冊(cè)中心的高可用,下面提供服務(wù)給注冊(cè)中心昭抒。
跟上一章中構(gòu)建服務(wù)一樣评也,創(chuàng)建一個(gè)服務(wù)后打包生成jar,然后啟動(dòng)服務(wù)并注冊(cè)到所有注冊(cè)中心上戈鲁。
# 高可用
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer1:1111/eureka/
啟動(dòng)多個(gè)服務(wù)
java -jar eureka-client.jar --server.port=8081
java -jar eureka-client.jar --server.port=8082
啟動(dòng)后仇参,刷新peer1/peer2控制臺(tái),可以看到2個(gè)服務(wù)婆殿,也可以調(diào)用服務(wù)測試接口http://desktop-7brumlo:8081/hello
有了高可用注冊(cè)中心诈乒,也提供了服務(wù),接下來是消費(fèi)服務(wù)了婆芦。
下面通過ribbon消費(fèi)服務(wù)提供者怕磨,可通過日志查看ribbon的負(fù)載均衡狀態(tài)。
創(chuàng)建一個(gè)gradle工程消约,配置文件如下:
dependencyManagement {
imports {
mavenBom 'org.springframework.cloud:spring-cloud-dependencies:Edgware.SR4'
}
}
dependencies {
compile('org.springframework.boot:spring-boot-starter')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-actuator')
compile 'org.slf4j:slf4j-api:1.7.14'
compile('org.springframework.cloud:spring-cloud-starter-hystrix')
compile('org.springframework.cloud:spring-cloud-starter-eureka')
compile('org.springframework.cloud:spring-cloud-starter-ribbon')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
application.properties文件如下:
spring.application.name=ribbon-consumer
server.port=9000
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer1:1111/eureka/
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=2000
上面配置了熔斷的時(shí)間間隔為2000毫秒肠鲫。
在啟動(dòng)類上添加超時(shí)熔斷標(biāo)簽,如下:
@EnableCircuitBreaker //超時(shí)熔斷
@EnableDiscoveryClient
@SpringBootApplication
public class CloudApplication {
@Bean
@LoadBalanced //請(qǐng)求時(shí)擁有客戶端負(fù)載均衡的能力
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(CloudApplication.class, args);
}
}
創(chuàng)建消費(fèi)controller或粮,如下:
@RestController
public class ConsumerController {
@Autowired
HelloService helloService;
@GetMapping(value = "/ribbon-consumer")
public String helloConsumer() {
return helloService.hello();
}
}
最后創(chuàng)建service导饲,調(diào)用要消費(fèi)的服務(wù),如下:
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "helloFallback", commandKey = "helloKey")
public String hello() {
StringBuilder result = new StringBuilder();
// GET
result.append(restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class).getBody()).append("<br>");
result.append(restTemplate.getForEntity("http://HELLO-SERVICE/hello1?name={1}", String.class, "didi").getBody()).append("<br>");
return result.toString();
啟動(dòng)消費(fèi)服務(wù)后氯材,消費(fèi)服務(wù)http://localhost:9000/ribbon-consumer
渣锦,可以看到以下日志
DynamicServerListLoadBalancer for client HELLO-SERVICE initialized: DynamicServerListLoadBalancer:
{NFLoadBalancer:name=HELLO-SERVICE,current list of Servers=[DESKTOP-7BRUMLO:8082, DESKTOP-7BRUMLO:8081],
Load balancer stats=Zone stats: {
defaultzone=[Zone:defaultzone; Instance count:2;
Active connections count: 0; Circuit breaker tripped count: 0;
Active connections per server: 0.0;]
日志上可以看到ribbon客戶端維護(hù)的SERVICE的服務(wù)列表,就按此信息輪詢?cè)L問氢哮,以實(shí)現(xiàn)基于客戶端的負(fù)載均衡袋毙。
若停掉一個(gè)服務(wù),可以看到ribbon會(huì)啟動(dòng)熔斷機(jī)制冗尤,過一會(huì)后就可以正常訪問了听盖,所有請(qǐng)求落到另一個(gè)服務(wù)上胀溺;若2個(gè)服務(wù)都正常,可以觀察服務(wù)輸出日志是按輪詢方式輸出的皆看。
學(xué)習(xí)交流仓坞,請(qǐng)加群:64691032