SpringCloud之Eureka:集羣搭建

上篇文章《SpringCloud之Eureka:服務發佈與調用例子》實現了一個簡單例子,此次對其進行改造,運行兩個服務器實例、兩個服務提供者實例,服務調用者請求服務,使其能夠進行集羣部署。html

集羣結構以下圖所示。java

 因爲開發環境只有一臺電腦,要構建集羣,須要修改hosts文件,在裏面添加主機名映射。web

127.0.0.1 slave1 slave2

 

1、服務器端spring

一、建立項目apache

開發工具: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:服務發佈與調用例子》。json

二、修改配置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/

三、修改啓動類代碼FirstEkServerApplication.javaapp

除了增長註解@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);
    }

}

2、編寫服務提供者

一、建立項目

IDEA中建立一個新的SpringBoot項目,除了名稱爲「first-cloud-provider」,其它步驟和上面建立服務器端同樣。

二、修改配置application.yml

spring:
  application:
    name: first-cloud-provider
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/

三、添加類 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;
    }
}

四、添加控制器 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;
    }
}

五、修改啓動類代碼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);
    }

}

 

3、編寫服務調用者

一、建立項目
IDEA中建立一個新的SpringBoot項目,除了名稱爲「first-cloud-invoker」,其它步驟和上面建立服務器端同樣。

二、修改配置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/

三、添加控制器 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;
    }
}

四、修改啓動類代碼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);
    }

}

 

4、編寫REST客戶端進行測試

一、建立項目

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

二、修改配置application.yml

server:
  port: 9001

三、修改啓動類代碼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();
    }
}

四、測試

(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次,可見已經達到負載均衡。

相關文章
相關標籤/搜索