Spring Boot2.0 服務治理:Spring Could Eureka

服務治理:Spring Could Eureka

目錄:

1 服務治理

2 服務註冊中心搭建(管理服務,提供註冊與發現)

3 註冊服務提供者(提供服務)

4 高可用註冊中心

5 註冊服務消費者(消費服務)

6 總結

介紹:

Spring Could Eureka是Spring Could Netfix(核心組件)中的一部分,主要負責微服務框架的服務治理功能。註冊中心主要提供註冊與發現功能,服務提供者提供服務,服務消費者消費服務。其具有Spring Boot風格的自動化配置。該節主要爲服務治理的簡單搭建。相關配置詳情見"Eureka配置詳解"。

服務端:註冊中心註解:@EnableEurekaServer

客戶端:消費,提供註解:@EnableDiscoveryClient

主要環境配置:jdk1.8、maven3.3.9、Spring Boot2.0、IDEA2017

1 服務治理

服務治理主要分爲服務註冊於服務發現,是微服務架構的核心與基礎。用以保證服務間的正常運行,降低維護成本。(服務多的時候尤爲重要)。

1.1 服務註冊

服務單元向註冊中心登記自己提供的服務。包含主機、端口號、版本號、通信協議等。註冊中心將根據服務名稱分類組織服務清單,當進程啓動時,註冊中心會維護該清單。除此之外服務註冊中心需要以心跳的方式監測服務是否可用,不可用需要從清單剔除,達到排查故障服務的效果。 --(怎麼監控到,怎麼剔除,缺少的服務(服務發現)怎麼解決?)

註冊中心會維護該清單如:
服務A: 192.168.0.100:8081;192.168.0.101:8082
服務B: 192.168.0.100:8080;192.168.0.104:8082;192.168.0.100:8081

1.2 服務發現

在服務治理框架下,服務間調用是通過服務名發起調用請求。如服務A:192.168.0.100:8081,192.168.0.101:8082位置可用。當調用服務 A時將採取輪詢調用(需要負載均衡)。但是爲了性能等,不會採用每次都向服務註冊中心獲取服務的方式。

2 服務註冊中心搭建

作用:該註冊中心用於管理服務提供者的基本運行狀況。註冊中心重啓,維護的服務表將清空。

主要環境配置:jdk1.8、maven3.3.9、Spring Boot 2.0

2.1 pom.xml

添加spring-cloud-starter-netflix-eureka-server

<?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 http://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.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</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>
        <!--euraka 2.0註冊中心-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

    <!--@EnableEurekaServer註解報錯的一種解決方式-->
    <!--<repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.BUILD-SNAPSHOT</version><!--spring boot 2.0 與1.0 配置時需要選擇對應版本-->
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <scope>compile</scope>
                <version>19.0</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2.2 application.properties

#端口
server.port= 1111
#項目名稱
#server.servlet.context-path=/eureka11

#ip 註冊中心ip地址
eureka.instance.hostname=localhost 
# 不向註冊中心註冊自己,,默認true
eureka.client.registerWithEureka=false
# 註冊中心不需要檢索服務,職責是維護服務是維護實例,默認true
eureka.client.fetchRegistry=false
eureka.instance.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
#本地關閉自我保護機制進行測試,默認true(未關閉)
eureka.server.enableSelfPreservation=false

2.3 Spring Boot啓動類

使用@EnableEurekaServer註解開啓註冊服務中心。

@SpringBootApplication
@EnableEurekaServer 
public class EurekaApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
        System.out.println("args = [" + args + "]");
    }

}

配置完成後,啓動EurekaApplication類main()方法。瀏覽器輸入http://localhost:1111/,結果如下圖。 Instances currently registered with Eureka欄無數據。如下圖: Alt text

3 註冊服務提供者

搭建服務,並將服務註冊當上面創建的註冊中心中。讓註冊中心統一管理服務。當服務在請求時,該服務會註冊到註冊中心,但是服務死亡時,註冊中心並不是馬上不知道, Eureka server和client之間每隔30秒會進行一次心跳通信,告訴server,client還活着。由此引出兩個名詞:

Renews threshold:server期望在每分鐘中收到的心跳次數

Renews (last min):上一分鐘內收到的心跳次數。

3.1 pom.xml (pom.xml與2.1中xml相同)

3.2 application.properties

將服務註冊到上面的註冊中心 http://localhost:8888/eureka/

# 端口
server.port= 8888

# 服務名稱
spring.application.name=hello-service
#將服務hello-service 註冊到 http://localhost:1111/eureka/
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

3.3 Spring Boot啓動類

@EnableDiscoveryClient
@SpringBootApplication
public class ProvideApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProvideApplication.class, args);
        System.out.println("args = [" + args + "]");
    }

}

測試接口

@RestController
@RequestMapping("/user")
public class UserController {
    /**獲取logger實例*/
    private final Logger logger = Logger.getLogger(getClass().toString());

    @Value("${server.port}")
    private String port;

    @Value("${spring.application.name}")
    private String hostname;

    @RequestMapping("/login")
    public String login(){
        logger.info("服務host:"+port+",service_id:"+hostname);
        return 服務host:"+port+",service_id:"+hostname;
    }
}

配置完成後,啓動DemoApplication類main()方法。瀏覽器輸入http://localhost:8888/user/login,請求完成後,出現"這是一個服務提供者!"。

刷新註冊中心http://localhost:1111/ ; Instances currently registered with Eureka欄出現數據。如下圖: Alt text

此時如果關閉服務hello-service,註冊中心顯示服務還存在。當心跳時間達到時,加入自我保護模式,說明此時有服務掛掉。如下圖: Alt text

4 高可用註冊中心

將註冊中心相互註冊,它既是註冊中心,也是服務提供者。考慮發生故障時。主要實現: application-peer1.properties :註冊中心peer1的serviceUr2

# 服務名稱
spring.application.name=eureka-service
#端口
server.port= 1111

#ip 註冊中心ip地址
eureka.instance.hostname=peer1 
eureka.client.serviceUrl.defaultZone=http://peer2:2222/eureka/

application-peer2.properties註冊中心peer2的serviceUr1

# 服務名稱
spring.application.name=eureka-service
#端口
server.port= 2222

#ip 註冊中心ip地址=主機名稱
eureka.instance.hostname=peer2 
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/

application.properties

# 服務名稱
spring.application.name=eureka-service

eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/;
http://peer2:2222/eureka/

/etc/hosts 加入

 127.0.0.1  peer1
 127.0.0.1  peer2

啓動:java -jar eureka-server-1.0.0.jar --spring.profiles-active=peer1(或者peer2)

注:peer1、peer2爲主機名稱,可以直接使用主機ip。需要配置參數eureka.instance.preferIpAddressTrue=true,默認爲flase。

5 服務消費者(服務發現與消費)

服務消費前準備:啓動註冊中心,啓動服務提供(端口8888,端口8800),

啓動命令:java -jar demo-0.0.1-SNAPSHOT.jar --server.port=8888 (或者8800)

服務消費者:服務發現由Eureka的客戶端完成,服務消費的任務由Ribbon(http和tcp的客戶端負載均衡器)完成,

接下來創建服務消費者:

5.1 pom.xml

添加:spring-cloud-starter-netflix-eureka-server;spring-cloud-starter-netflix-ribbon

<?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 http://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.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>customer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>customer_server</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>

        <!--euraka 2.0註冊客戶端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <!--ribbon 用於服務消費-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.BUILD-SNAPSHOT</version><!--spring boot 2.0 與1.0 配置時需要選擇對應版本-->
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <scope>compile</scope>
                <version>19.0</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

5.2 application.properties

# 端口
server.port= 8089

# 服務名稱
spring.application.name=ribbon-customer

#將服務hello-service 註冊到 http://localhost:1111/eureka/
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

5.3 Spring Boot啓動類

配置RestTemplate,註解@EnableDiscoveryClient

@EnableDiscoveryClient
@SpringBootApplication
public class CustomerApplication {

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(CustomerApplication.class, args);
    }
}

測試類:

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/login")
    public String login()
    {
        //hello-service爲服務提供者的服務名稱
        return "我是一個消費者去調用==》"+restTemplate.getForEntity("http://hello-service/user/login",String.class);
    }
}

啓動後,進入測試。 註冊中心顯示如下圖: Alt text

測試接口輸入:http://localhost:8089/user/login。結果將輪番調用hello-service服務的8888與8800端口。

6 總結

  1. 服務統一交由註冊中管理:eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

  2. 消費者調用服務時,直接調用服務名稱。spring.application.name=ribbon-customer

參考:

1 《Spring Could 微服務實戰》 翟永超 電子工業出版社 2017.5

參考網站:http://blog.didispace.com/Spring-Cloud基礎教程/

源碼地址:

https://github.com/zlk19921105/spring_cloud

其中:註冊中心eureka-server;服務提供provide-services;服務消費customer-server

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章