Spring Cloud_4_Eureka集羣搭建

Eureka集羣搭建

  • 搭建Eureka集羣

1、Eureka集羣搭建

  • 在介紹Eureka的時候,服務器實例、服務提供者實例都是隻啓動了一個,並沒有體現高可用性
  • 本小節將對前面的Eureka應用進行改造,使其可以進行集羣部署

1.1、集羣結構圖

  • 上節改造前

  • 本案例將運行兩個服務器實例、兩個服務提供者實例,然後服務調用者請求服務
  • 本節改造後

Eureka服務器A,Eureka服務器B(114電話查詢平臺A接線員,B接線員)
服務提供者A,服務提供者B(多人向警察局撥打電話,人手不足,警察局也提供了A,B接線員)
Eureka客戶端服務調用者(不在乎有多少接線員,只知道可以向114平臺查詢到對應想要的電話號碼)

  • 在上一節中的Eureka應用,使用的是瀏覽器訪問Eureka的服務調用者
  • 改造之後,爲了能看到負載均衡的效果,會編寫一個HttpClient的REST客戶端訪問服務調用者發佈的服務
  • 本節的開發環境只有一臺電腦,操作系統爲Windows,如果要構建集羣,需要修改hosts文件,爲其添加主機名的映射
  • 修改C:\Windows\System32\drivers\etc\hosts文件,添加127.0.0.1 slave1 slave2

2、改造服務端

  • 新建Maven項目:atm_eureka_server_AB
  • 使用maven配置與上一節一致

2.1、修改配置文件

  • 由於需要對同一個應用啓動兩次,因此需要在配置文件中使用profiles
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/
  • 配置了兩個profiles,分別爲slave1和slave2
  • 在slave1中,配置了應用端口8761,主機名爲slave1,當使用 slave1這個profiles啓動服務器時,將會向http://slave2:8762/eureka註冊自己
  • 使用slave2來啓動服務器時,會向http://slave1:8761/eureka註冊自己
  • 簡單點說 , 就是兩個服務器啓動後 , 它們會互相註冊 。

2.2、修改啓動類

  • 讓類在啓動時,讀取控制檯的輸入,決定使用那個profiles來啓動服務器
package com.atm.cloud;

import java.util.Scanner;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class MyApplicationServer {

    public static void main(String[] args) {

        //讀取控制檯輸入,決定使用哪個profiles
        Scanner scanner=new Scanner(System.in);

        String profiles=scanner.nextLine();

        //SpringApplication.run(MyApplicationServer.class, args);

        new SpringApplicationBuilder(MyApplicationServer.class).profiles(profiles).run(args);
    }

}
  • 啓動類中,先讀取控制檯的輸入,再調用profiles方法來設置啓動的profiles
  • 啓動服務器會拋出異常, 異常原因在上一節已經闡述,此處不再理會







3、改造服務提供者

  • 服務提供者也需要啓動兩個實例
  • 服務提供者的改造與服務端類似
  • 複製或者新建上一節中“服務提供者”,Maven項目:atm_eureka_provider_AB

3.1、修改配置文件

spring:
 application:
  name: first-cloud-provider
eureka:
 instance:
  hostname: localhost
 client:
  serviceUrl:
   defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/
  • 注意註冊的application.name爲: first-cloud-provider

3.2、修改控制器

  • 啓動類使用了profiles方法來設置啓動端口
  • 爲了能看到效果,還需要改造控制器,將服務調用者請求的URL保存起來並返回
package com.atm.cloud;

import javax.servlet.http.HttpServletRequest;

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;

@RestController
public class MyController {

    @RequestMapping(value = "/person/{personId}", method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public Person findPerson(@PathVariable("personId")Integer personId,HttpServletRequest request){
        Person person=new Person();

        person.setId(personId);
        person.setAge(18);
        person.setName(request.getRequestURL().toString());

        return person;
    }
}
  • 控制器的findPerson方法,將請求的URL保存到Person實例的name屬性中,調用服務後,可以通過name屬性來查看請求的URL

3.3、修改啓動類

  • 爲了避免端口衝突,啓動時讀取控制檯輸入,決定使用哪個端口來啓動
package com.atm.cloud;

import java.util.Scanner;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class MyApplicationProvider {

    public static void main(String[] args) {

        //讀取控制檯輸入,避免端口衝突
        Scanner scanner=new Scanner(System.in);

        String port=scanner.nextLine();

        new SpringApplicationBuilder(MyApplicationProvider.class).properties(
                "server.port=" + port).run(args);
    }
}




4、改造服務調用者

  • 本案例中的服務調用只需要啓動一個實例
  • 複製/新建上一節的“服務提供者”,Maven項目:atm_eureka_invoker_AB

4.1、修改配置文件

  • 修改的配置,將服務調用註冊到兩個服務器上
server:
 port: 9000
spring:
 application:
  name: first-cloud-invoker
eureka:
 instance:
  hostname: localhost
 client:
  serviceUrl:
   defaultZone: http://localhost:8761/eureka/,http:// localhost:8761/eureka/

4.2、修改控制器

package com.atm.cloud;

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 restTemplate = getRestTemplate();

        // 根據應用名稱調用服務
        String json = restTemplate.getForObject(
                "http://first-cloud-provider/person/1", String.class);

        return json;
    }
}

5、REST客戶端

  • 本案例使用的是HttpClient,HttpClient是Apache提供的一個Http工具包
  • 新建Maven項目:atm_eureka_REST_client

5.1、引入依賴

<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 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.atm.cloud</groupId>
    <artifactId>atm_eureka_REST_client</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>atm_eureka_REST_client Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <!-- HttpClient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>

    </dependencies>
    <build>
        <finalName>atm_eureka_REST_client</finalName>
    </build>
</project>

5.2、新建啓動類

package atm_eureka_REST_client;

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;

public class MyApplicationRESTClient {

    public static void main(String[] args) {

        //創建默認的HttpClient
        CloseableHttpClient client=HttpClients.createDefault();

        //調用6次服務並輸出結果
        for (int i = 0; i < 6; i++) {

            //調用GET方法請求服務
            HttpGet httpGet=new HttpGet("http://location:9000/router");

            try {
                //獲取響應
                HttpResponse response=client.execute(httpGet);

                //根據響應解析出字符串
                System.out.println(EntityUtils.toString(response.getEntity()));

            } catch (Exception e){
                System.out.println("Exception --->>>"+e);
            }

        }

    }

}
  • 在main方法,調用了6次9000端口的router服務並輸出結果

  • 啓動兩個服務端,控制端分別輸入“slave1”和“slave2”
  • 啓動兩個服務提供者,控制檯分別輸入“8081”和“8082”
  • 啓動服務調用者
  • 運行MyApplicationRESTClient的main方法


  • 根據輸出內容可知:8081與8082端口,分別被請求了3次,可見已經達成了負載均衡的目的
  • 關於負載均衡更詳細的內容,將在後面章節中講解
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章