探索SpringCloud 二(服务注册和发现)

SpringCloud的服务注册和服务发现是由Eureka来完成的。
使用IDEA来做demo(包含:高可用注册中心,服务注册与发现,服务调用,负载均衡)
*注:创建项目细节不贴图了
总体项目结构:
这里写图片描述

一、启动服务注册中心

1、创建SpringCloud项目
这里写图片描述
这里写图片描述

项目pom.xml

<?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>

    <groupId>com.zbb</groupId>
    <artifactId>spring-cloud</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <name>springclouddemo</name>
    <description>Demo project for Spring Cloud</description>

    <modules>
        <module>eurekaservice</module>
        <module>helloservice</module>
        <module>hellocustomer</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Dalston.SR4</spring-cloud.version>
    </properties>

    <dependencies>
        <!--服务注册中心必要依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <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>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.4.2</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2、在项目下创建服务注册中心子项目 eurekaservice
这里写图片描述

子项目(服务注册中心)pom.xml文件:

<?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">
    <parent>
        <artifactId>spring-cloud</artifactId>
        <groupId>com.zbb</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zbb</groupId>
    <artifactId>eureka-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
    <!--服务注册中心必要依赖-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
    </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3、设置该子项目为服务注册中心

想要开启一个注册中心只需要两步
(1)在启动类(xxxxApplication.java))上添加一条注解@EnableEurekaServer

package com.zbb.eurekaservice;

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

@EnableEurekaServer                 //开启服务注册中心
@SpringBootApplication
public class EurekaServiceApplication {
    public static void main(String[] args)
    {
        SpringApplication.run(EurekaServiceApplication.class, args);
    }
}

(2) 在application.properties中设置注册中心的配置

#注册中心端口
server.port=1111

#主机名
eureka.instance.hostname=localhost

#表示本应用是否是向注册中心注册自己(配置高可用的时候需要设置为true,也就是默认值)
eureka.client.register-with-eureka=false

#是否去检索服务
eureka.client.fetch-registry=false

#eureka服务地址
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/

4、如图启动成功
这里写图片描述

打开浏览器输入:http://localhost:1111/
这时页面会显示Eureka的管理界面
这里写图片描述

Instances currently registered with Eureka下面表示的就是发现的服务,因为现在还没有服务注册,所以没有发现服务。

注:出现一行红色大字EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
这是一种自我保护机制。Eureka Server在运行期间,会统计心跳失败的比例在15分钟之内是否低于85%,如果出现低于的情况(在单机调试的时候很容易满足,实际在生产环境上通常是由于网络不稳定导致),Eureka Server会将当前的实例注册信息保护起来,同时提示这个警告。

二、注册服务提供者

1、创建一个服务提供者的子项目helloservice。(略)
2、添加依赖(pom.xml)

<?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">
    <parent>
        <artifactId>spring-cloud</artifactId>
        <groupId>com.zbb</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>helloservice</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

    </dependencies>
</project>

3、创建Controller

package com.zbb.controller;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloServiceController {

    private final Logger logger = Logger.getLogger(getClass());

    @Autowired
    DiscoveryClient discoveryClient;    //自动注入DiscoveryClinet

    @RequestMapping(value = "/hello" , method = RequestMethod.GET)
    public String sayHello(){

        ServiceInstance serviceInstance = discoveryClient.getLocalServiceInstance();    //获得service实例

        logger.info("/hello , host:"+serviceInstance.getHost()+"/n"+"/service_id:"+serviceInstance.getServiceId());

        return "成功访问服务";
    }

}

4、激活DiscoveryClient实现

在启动类添加注解:@EnableDiscoveryClient

package com.zbb.helloservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan("com.zbb.*")     //组件扫描
@EnableDiscoveryClient          //激活DiscoveryClient实现
@SpringBootApplication         
public class HelloServiceApplication {
    public static void main(String[] args){
        SpringApplication.run(HelloServiceApplication.class,args);
    }
}
注:激活DiscoveryClient实现(自动化配置,创建DiscoveryClient接口的实现EnableDiscoveryClient)

5、修改application.properties,指定注册中心

#设置服务名
spring.application.name=hello-service

#指定服务注册中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka

6、启动
先启动注册中心,再启动本服务。
这里写图片描述
访问:http://localhost:1111/
这里写图片描述

7、访问http://localhost:8080/hello
这里写图片描述
查看控制台会发现打印出以下信息:
这里写图片描述
这里打印的信息就是刚刚在HelloServiceController中注入的DiscoveryClient接口对象从服务注册中心获取的服务信息。

* 三、高可用注册中心搭建*

EurekaServer在设计的时候就开始考虑高可用的问题,在Eureka的服务治理设计中,所有的节点即是服务提供方,也是服务消费方,注册中心也不会例外。
简单点来讲就是使多个注册中心相注册服务,我们以上面eurekaservice为基础进行搭建

1、创建两个properties文件(3个)

application-peer1.properties

#服务名
spring.application.name=eureka-server
#注册中心-01 端口
server.port=1111

#注册中心主机名
eureka.instance.hostname=peer1

#指定另外的注册中心
eureka.client.serviceUrl.defaultZone=http://peer2:1112/eureka/,http://peer3:1113/eureka/

application-peer2.properties

#服务名
spring.application.name=eureka-server
#注册中心-01 端口
server.port=1112

#注册中心主机名
eureka.instance.hostname=peer2

#指定另外的注册中心
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer3:1113/eureka/

application-peer3.properties

#服务名
spring.application.name=eureka-server
#注册中心-01 端口
server.port=1113

#注册中心主机名
eureka.instance.hostname=peer3

#指定另外的注册中心
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/

2、修改服务生产者(helloservice)的配置文件application.properties

#设置服务名
spring.application.name=hello-service

#指定服务注册中心地址
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/,http://peer3:1113/eureka/

3、添加对register1、register2、register3的转换

需要在/etc/host文件中添加对应关系
windows系统host文件路径C:\Windows\System32\drivers\etc
修改完成后的host如下:

# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#   127.0.0.1       localhost
#   ::1             localhost
127.0.0.1 peer1
127.0.0.1 peer2
127.0.0.1 peer3

4、通过spring.profiles.active来指定启动注册中心

java -jar eureka-server-0.0.1-SNAPSHOT.jar - -spring.profiles.active=peer1
java -jar eureka-server-0.0.1-SNAPSHOT.jar - -spring.profiles.active=peer1
java -jar eureka-server-0.0.1-SNAPSHOT.jar - -spring.profiles.active=peer1

启动成功后访问http://localhost:1111/http://localhost:1112/http://localhost:1113/
这里只截图http://localhost:1111/
这里写图片描述
可以明显看到发现服务EUREKA-SERVER
Application AMIs Availability Zones Status
EUREKA-SERVER n/a (3) (3) UP (3) - a-PC:eureka-server:1111 , a-PC:eureka-server:1112 , a-PC:eureka-server:1113

5、通过server.port来指定启动注册中心
分别启动两个生产者
java -jar helloservice-1.0-SNAPSHOT.jar –server.port=8081
java -jar helloservice-1.0-SNAPSHOT.jar –server.port=8082
完成后发现,EUREKA-SERVER三个,HELLO-SERVICE两个。
这里写图片描述

四、注册服务消费

1、创建服务消费子项目 hellocustomer(略)
2、添加依赖(pom.xml)

<?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">
    <parent>
        <artifactId>spring-cloud</artifactId>
        <groupId>com.zbb</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>hellocustomer</artifactId>


    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
            <version>1.3.4.RELEASE</version>
        </dependency>
    </dependencies>

</project>

3、开启eureka客户端
在HelloCustomerApplication.java中添加@EnableDiscoveryClient

package com.zbb.hellocustomer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.client.RestTemplate;

@ComponentScan("com.zbb.*")
@EnableDiscoveryClient      //让该应用注册成为eureka客户端,以获得服务发现的能力
@SpringBootApplication
public class HelloCustomerApplication {

    @Bean
    @LoadBalanced                   //开启客户端负载均衡
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args){
        SpringApplication.run(HelloCustomerApplication.class, args);
    }
}

4、创建Controller (CustomerController.java)

package com.zbb.contorller;

import org.springframework.beans.factory.annotation.Autowired;
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
public class CustomerController {

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping(value = "/hello-customer" , method = RequestMethod.GET)
    public String HelloController(){
         return  restTemplate.getForEntity("http://hello-service/hello" , String.class).getBody();
    }
}

5、修改配置文件 application.properties

#服务名
spring.application.name=ribbon-consumer
#注册中心-01 端口
server.port=9000


#指定另外的注册中心
eureka.client.serviceUrl.defaultZone=http://peer1:1111/eureka/,http://peer2:1112/eureka/,http://peer3:1113/eureka/

6、启动消费者服务

这里写图片描述
我们会发现有三个注册中心服务可用域有三个,生产者服务可用域两个,消费者服务一个

7、访问消费者服务
http://localhost:9000/hello-customer
这里写图片描述
我们发现成功的访问了生产者服务。

现在我停止一个注册中心,看看会有什么效果,停止peer1
这里写图片描述
我们发现peer1状态变为down。再次调用生产者服务发现依然可以调用成功!

end

猜你喜欢

转载自blog.csdn.net/u010994966/article/details/78338766