搭建eureka集羣
- 新建一個boot項目
File-》new-》project
如圖選擇-》next-》起名字如下
->next -》finish
- 新建3個註冊中心
以三個註冊中心爲例,想多的自己加
項目名字上-》new-》module
-》next-》起名字-》next
選擇依賴
Web —spring web////這個就別選了,截圖截多一個。選後兩個就行
Security ----Spring Security
Spring Cloud Discovery----Eureka Server
修改pom.xml,解決java8版本的問題,後面每個服務都要改這個,我的idea默認jdk6,導致啓動失敗,加了這個就默認爲JDK1.8了
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal><!--可以把依賴的包都打包到生成的Jar包中-->
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<!--指定jdk版本-->
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
配置application.yml
注意defaultZone,本例是三個註冊中心,中心1配置地址2、3,中心2配置地址3、1,中心3配置地址1、2。注意順序,
對於註冊中心eureka默認優先註冊到最前面那個,也就是1註冊到2,2註冊到3,3註冊到1.
當其中一個註冊中心死掉後,纔會註冊到其他地方。如2死掉了,1會註冊到第二個地址3上面,結果就成了1註冊到3,3註冊到1.
eureka:
instance:
hostname: localhost
client:
# eureka.client.registerWithEureka:false 因爲自己是爲註冊中心,不需要自己註冊自己 集羣模式下改爲 ture,註冊到其他註冊中中心
# 是否將該實例信息註冊到其他eureka server上;如果設置爲false,那麼該server無法被其他server發現,但是仍然可以發現其他server
# fetchRegistry:false來表明自己是一個eureka server.
registerWithEureka: true
#表示是否向eureka註冊服務,即在eureka中註冊自己,默認爲true,此處應該設置爲true,只有一個註冊中心時爲false;
#是否允許該客戶端從eureka server上獲取註冊信息
fetchRegistry: true
serviceUrl:
# 集羣模式:
defaultZone: http://admin:admin2@${eureka.instance.hostname}:8762/eureka/,http://admin:admin3@${eureka.instance.hostname}:8763/eureka/
# 單例模式:
#defaultZone: http://admin:admin1${eureka.instance.hostname}:8761/eureka/
#沒有密碼時,去掉security依賴,配置: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
server:
#設爲false,關閉自我保護,即Eureka server在雲心光器件會去統計心跳失敗比例在15分鐘之內是否低於85%,如果低於85%,EurekaServer
#會將這些事例保護起來,讓這些事例不會過期,但是在保護器內如果剛哈這個服務提供者非正常下線了,此時服務消費者會拿到一個無效的服務
#實例,此時調用會失敗,對於這個問題需要服務消費者端有一些容錯機制,如重試、斷路器等;
enable-self-preservation: false
#掃描失效服務的間隔時間(單位是毫秒,摩恩是60*1000),即60s
eviction-interval-timer-in-ms: 10000
server:
#服務端口號
port: 8761
spring:
application:
name: a-server1
# #安全登入用戶設置 ####******** 用戶名密碼,三個項目建議不一樣
security:
user:
name: admin
password: admin1
其他兩個按這個配置,記得改defaultZone,和password
修改啓動類
加兩個註解就可以了。
@EnableEurekaServer
@SpringBootApplication
public class AiServer1Application {
public static void main(String[] args) {
SpringApplication.run(AiServer1Application.class, args);
}
}
本來這樣就可以啓動了,但是我們配置了security安全驗證,
而新版(Spring Cloud 2.0 以上)的security默認啓用了csrf檢驗,要在eurekaServer端配置security的csrf檢驗爲false
新建一個類WebSecurityConfig,關閉csrf檢驗
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
super.configure(http);
}
}
其他兩個按這個寫,到此一個簡單的eureka集羣就搭建完成了。
啓動會報錯,不用管,這個是註冊到其他註冊中心時沒掃描到,原因是啓動註冊中心1時2還沒啓動,總得有個先後,都啓動了就好了。
com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
登錄http://IP:8761/
登錄http://IP:8762/
登錄http://IP:8763/
本地啓動要輸入密碼
可以看出,1註冊在2,2註冊在3,3註冊在1.
註冊中心完成。
可以嘗試關閉其中某個看看註冊情況。可能有時差大概30s。
搭建服務提供者client
筆者將上述註冊中心佈置到了服務器。所以服務提供者就按照服務器配置了,本地的話,把ip改爲localhost就行。
新建提供者1
項目名字-》new-》mudule-》next-》起名字-》next
選擇依賴(兩個)
Web —spring web
Spring Cloud Discovery----Eureka Server
配置application.yml
spring:
application:
name: ai-client1
server:
port: 8769
eureka:
instance:
# 服務提供者地址
hostname: localhost
# 註冊中心ip(根據實際,本地寫localhost)
hostname1: 47.102.111.111
client:
serviceUrl:
# 集羣時,其實只需要配置一個地址,當這個地址的註冊中心掛掉後,會自動註冊到其他註冊中心
# 配置多個註冊中心地址的好處是:啓動之前,某個註冊中心掛掉了,會拋出異常,但是也會正常註冊到其他某個註冊中心
defaultZone: http://admin:admin1@${eureka.instance.hostname1}:8761/eureka/,http://admin:admin2@${eureka.instance.hostname1}:8762/eureka/,http://admin:admin3@${eureka.instance.hostname1}:8763/eureka/
啓動類
@RestController
@EnableEurekaClient
@SpringBootApplication
public class AiClient1Application {
public static void main(String[] args) {
SpringApplication.run(AiClient1Application.class, args);
}
/**
* 假如這個客戶端要提供一個getUser的方法
* @return
*/
@GetMapping(value = "/getUser")
@ResponseBody
public Map<String,Object> getUser(@RequestParam Integer id){
Map<String,Object> data = new HashMap<String,Object>();
data.put("id",id);
data.put("userName","admin");
data.put("from","provider-A");
return data;
}
}
新建提供者2
內容跟提供者1一樣。
爲了測試負載均衡,不要改服務名字,必須保持一致。
spring.application.name=ai-client1
修改一下端口號和輸出結果就行,不同輸出結果驗證是哪個服務處理的請求。
如data.put(“from”,“provider-B1111111111”);
能看出不同就行。
啓動提供者,發現3號註冊中心會有這兩個服務
搭建服務消費者customer
搭建一個消費者customer
新建流程通服務提供者。
application.yml配置如下
eureka:
instance:
# 服務提供者地址
hostname: localhost
# 註冊中心ip(根據實際,本地寫localhost)
hostname1: 47.102.111.111
client:
serviceUrl: #註冊中心的註冊地址
# defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/
defaultZone: http://skyworth:skyworth1@${eureka.instance.hostname1}:8761/eureka/,http://skyworth:skyworth2@${eureka.instance.hostname1}:8762/eureka/,http://skyworth:skyworth3@${eureka.instance.hostname1}:8763/eureka/
server:
port: 8759 #服務端口號
spring:
application:
name: service-consumer #服務名稱--調用的時候根據名稱來調用該服務的方法
修改啓動類
/**
* Eureka客戶端-消費者
*/
@RestController
@EnableEurekaClient
@SpringBootApplication
public class AiConsumer1Application {
@Autowired
RestTemplate restTemplate;
public static void main(String[] args) {
SpringApplication.run(AiConsumer1Application.class, args);
}
/**
* 實例化RestTemplate
* @return
*/
@LoadBalanced
@Bean
public RestTemplate rest() {
return new RestTemplate();
}
/**
* Rest服務端使用RestTemplate發起http請求,然後得到數據返回給前端----gotoUser是爲了區分getUser怕小夥伴暈頭
* @param id
* @return
*/
@GetMapping(value = "/gotoUser")
@ResponseBody
public Map<String,Object> getUser(@RequestParam Integer id){
Map<String,Object> data = new HashMap<String,Object>();
/**
* 小夥伴發現沒有,地址居然是http://service-provider
* 居然不是http://127.0.0.1:8082/
* 因爲他向註冊中心註冊了服務,服務名稱service-provider,我們訪問service-provider即可
*
* 注意要容錯,當發生錯誤時重新掉這個接口,防止發生某個服務掛掉,請求失敗的情況。
*/
data = restTemplate.getForObject("http://ai-client1/getUser?id="+id, Map.class);
return data;
}
}
啓動消費者,發現3號註冊中心會有這個服務。
訪問地址:http:localhost:8759/gotoUser?id=1
多次訪問,發現會分別從服務1,服務2 返回結果。(服務1,2 返回結果要設置的不一樣,才能看出來的。)
總結幾個坑
1.解決java8版本的問題,後面每個服務都要改這個,我的idea默認jdk6,導致啓動失敗,加了這個就默認爲JDK1.8了
2.新版(Spring Cloud 2.0 以上)的security默認啓用了csrf檢驗,要在eurekaServer端配置security的csrf檢驗爲false
3.使用了安全驗證,註冊地址要加上username:password@,
http://username:password@${eureka.instance.hostname}:8762/eureka/
4.將註冊中心部署到服務器之後,如果服務要連接服務時,
要設置eureka.instance.hostname=localhost,如果寫成服務器ip,連接會成功,但是消費者會調用失敗,因爲跳轉的時候會跳轉到,服務器上的這個服務,而實際的服務在本地。