上篇文章《SpringCloud之Eureka:服務發佈與調用例子》實現了一個簡單例子,這次對其進行改造,運行兩個伺服器實例、兩個服務提供者實例,服務調用者請求服務,使其可以進行集群部署。 ...
上篇文章《SpringCloud之Eureka:服務發佈與調用例子》實現了一個簡單例子,這次對其進行改造,運行兩個伺服器實例、兩個服務提供者實例,服務調用者請求服務,使其可以進行集群部署。
集群結構如下圖所示。
由於開發環境只有一臺電腦,要構建集群,需要修改hosts文件,在裡面添加主機名映射。
127.0.0.1 slave1 slave2
一、伺服器端
1、創建項目
開發工具:IntelliJ IDEA 2019.2.2
IDEA中創建一個新的SpringBoot項目,名稱為“first-cloud-server”,SpringBoot版本選擇2.1.9,在選擇Dependencies(依賴)的界面勾選Spring Cloud Discovert ->
Eureka Server,創建完成後的pom.xml配置文件自動添加SpringCloud最新穩定版本依賴,當前為Greenwich.SR3。
pom.xml完整內容可參考上篇文章《SpringCloud之Eureka:服務發佈與調用例子》。
2、修改配置application.yml
由於需要對同一個應用程式啟動兩次,因此需要使用profiles配置。
下麵配置了兩個profiles,名稱分別為slave1和slave2,當使用slave1啟動伺服器後,會向http://slave2:8762/eureka/註冊自己,當使用slave2啟動伺服器後,會向
http://slave1:8761/eureka/註冊自己,即兩個伺服器啟動後,互相註冊。
server: port: 8761 spring: application: name: first-cloud-server profiles: slave1 eureka: instance: hostname: slave1 client: serviceUrl: defaultZone: http://slave2:8762/eureka/ --- server: port: 8762 spring: application: name: first-cloud-server profiles: slave2 eureka: instance: hostname: slave2 client: serviceUrl: defaultZone: http://slave1:8761/eureka/
3、修改啟動類代碼FirstEkServerApplication.java
除了增加註解@EnableEurekaServer,還讓類在啟動時讀取控制台輸入,決定使用哪個profiles來啟動伺服器。
package com.example.firstcloudserver; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; import java.util.Scanner; @SpringBootApplication @EnableEurekaServer public class FirstCloudServerApplication { public static void main(String[] args) { //SpringApplication.run(FirstCloudServerApplication.class, args); Scanner scan = new Scanner(System.in); String profiles = scan.nextLine(); new SpringApplicationBuilder(FirstCloudServerApplication.class) .profiles(profiles).run(args); } }
二、編寫服務提供者
1、創建項目
IDEA中創建一個新的SpringBoot項目,除了名稱為“first-cloud-provider”,其它步驟和上面創建伺服器端一樣。
2、修改配置application.yml
spring: application: name: first-cloud-provider eureka: instance: hostname: localhost client: serviceUrl: defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
3、添加類 User.java
package com.example.firstcloudprovider; public class User { private Integer id; private String name; private String message; public User(Integer id, String name){ this.id = id; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
4、添加控制器 UserController.java
package com.example.firstcloudprovider; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @RestController public class UserController { @RequestMapping(value = "/user/{userId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public User findUser(@PathVariable("userId") Integer userId, HttpServletRequest request){ User user = new User(userId, "gdjlc"); user.setMessage(request.getRequestURL().toString()); return user; } }
5、修改啟動類代碼FirstCloudProviderApplication.java
除了增加註解@EnableEurekaClient,還讓類在啟動時讀取控制台輸入,決定使用哪個埠啟動伺服器。
package com.example.firstcloudprovider; //import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import java.util.Scanner; @SpringBootApplication @EnableEurekaClient public class FirstCloudProviderApplication { public static void main(String[] args) { //SpringApplication.run(FirstCloudProviderApplication.class, args); Scanner scan = new Scanner(System.in); String port = scan.nextLine(); new SpringApplicationBuilder(FirstCloudProviderApplication.class).properties("server.port=" + port).run(args); } }
三、編寫服務調用者
1、創建項目
IDEA中創建一個新的SpringBoot項目,除了名稱為“first-cloud-invoker”,其它步驟和上面創建伺服器端一樣。
2、修改配置application.yml
server: port: 9000 spring: application: name: first-cloud-invoker eureka: instance: hostname: localhost client: serviceUrl: defaultZone: http://slave1:8761/eureka/,http://slave2:8762/eureka/
3、添加控制器 InvokerController.java
package com.example.firstcloudinvoker; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController @Configuration public class InvokerController { @Bean @LoadBalanced public RestTemplate getRestTemplate(){ return new RestTemplate(); } @RequestMapping(value = "/router", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public String router(){ RestTemplate restTpl = getRestTemplate(); //根據應用名稱調用服務 String json = restTpl.getForObject("http://first-cloud-provider/user/1", String.class); return json; } }
4、修改啟動類代碼FirstCloudInvokerApplication.java
添加註解@EnableDiscoveryClient,使得服務調用者可以去Eureka中發現服務。
package com.example.firstcloudinvoker; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class FirstCloudInvokerApplication { public static void main(String[] args) { SpringApplication.run(FirstCloudInvokerApplication.class, args); } }
四、編寫REST客戶端進行測試
1、創建項目
IDEA中創建一個新的SpringBoot項目,名稱為“first-cloud-rest-client”,SpringBoot版本選擇2.1.9,在選擇Dependencies(依賴)的界面勾選Web->Spring Web。
在pom.xml中增加httpclient依賴。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.9.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>first-cloud-rest-client</artifactId> <version>0.0.1-SNAPSHOT</version> <name>first-cloud-rest-client</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>View Code
2、修改配置application.yml
server: port: 9001
3、修改啟動類代碼FirstCloudRestClientApplication.java
編寫調用REST服務的代碼
package com.example.firstcloudrestclient; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class FirstCloudRestClientApplication { public static void main(String[] args) { SpringApplication.run(FirstCloudRestClientApplication.class, args); } @RequestMapping("/") public String testHttpClient(){ StringBuilder sb = new StringBuilder(); try{ CloseableHttpClient httpClient = HttpClients.createDefault(); for(int i=0;i<10;i++){ HttpGet httpGet = new HttpGet("http://localhost:9000/router"); HttpResponse response = httpClient.execute(httpGet); sb.append(EntityUtils.toString(response.getEntity()) + "<br />"); } }catch(Exception ex){ return ex.getMessage(); } return sb.toString(); } }
4、測試
(1)啟動兩個伺服器端,在控制臺中分別輸入slave1和slave2啟動。
(2)啟動兩個服務提供者,在控制臺中分別輸入8763和8764啟動。
(3)啟動服務調用者。
(4)啟動REST客戶端。
瀏覽器訪問 http://slave1:8761/,頁面如下
瀏覽器訪問 http://slave2:8762/,頁面如下
瀏覽器訪問 http://localhost:8763/user/1,頁面輸出:
{"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"}
瀏覽器訪問 http://localhost:8764/user/1,頁面輸出:
{"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"}
瀏覽器訪問 http://localhost:9000/router,多次刷新頁面,頁面輸出在8763和8764切換:
{"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"}
{"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"}
瀏覽器訪問 http://localhost:9001/,頁面輸出
{"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"} {"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"} {"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"} {"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"} {"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"} {"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"} {"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"} {"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"} {"id":1,"name":"gdjlc","message":"http://localhost:8764/user/1"} {"id":1,"name":"gdjlc","message":"http://localhost:8763/user/1"}
請求了10次,8763和8764分別被請求5次,可見已經達到負載均衡。