SpringCloud(一)搭建Eureka注册中心

2019-04-18  本文已影响0人  冰三尺

注册中心就是一个统一管理管理不同的微服务项目的ip地址的一个服务, 不同的服务将自己的服务注册到注册中心上, 消费者会从注册中心上去寻找自己需要的RPC远程调用地址之后, 最终以HTTPClient技术实现远程调用.

1. 注册中心环境搭建

新建eureka项目
依赖环境

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

yml配置

###服务端口号
server:
  port: 8100
###eureka 基本信息配置
eureka:
  instance:
    ###注册到eurekaip地址
    hostname: 127.0.0.1
  client:
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    register-with-eureka: false
    fetch-registry: false

创建启动类

@EnableEurekaServer
@SpringBootApplication
public class AppEureka {

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

}
屏幕快照 2019-04-18 上午11.04.24.png

2.注册服务提供者

新建Provider项目
添加依赖

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

yml配置

server:
  port: 8000
spring:
  application:
    name: app-provider
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8100/eureka
    register-with-eureka: true
    fetch-registry: true

创建启动类

@SpringBootApplication
@EnableEurekaClient
public class App {
    // @EnableEurekaClient 将当前服务注册到eureka上
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

刷新eureka会看到

屏幕快照 2019-04-18 下午3.08.59.png
Application为spring.application.name: app-provider

2.注册服务消费者

新建custom项目
添加依赖

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

    </dependencies>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

yml配置

server:
  port: 8001
spring:
  application:
    name: app-customer
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8100/eureka
    register-with-eureka: true
    fetch-registry: true

消费者Controller

@RestController
public class OrderControler {

    // RestTemplate 是有SpringBoot Web组件提供 默认整合ribbon负载均衡器
    // rest方式底层是采用httpclient技术
    @Autowired
    private RestTemplate restTemplate;

    /**
     * 在SpringCloud 中有两种方式调用 rest、fegin(SpringCloud)
     * 
     * @return
     */

    @RequestMapping("/getOrder")
    public String getOrder() {
        // 有两种方式,一种是采用服务别名方式调用,另一种是直接调用 使用别名去注册中心上获取对应的服务调用地址
        String url = "http://127.0.0.1:8000/getMember";
        String result = restTemplate.getForObject(url, String.class);
        System.out.println("调用服务result:" + result);
        return result;
    }

}

rest底层使用的是httpclient技术来实现远程调用String url = "http://127.0.0.1:8000/getMember", 这个直接走的是ip地址. 不会走注册中心

创建启动类

@SpringBootApplication
@EnableEurekaClient
public class AppOrder {
    public static void main(String[] args) {
        SpringApplication.run(AppOrder.class, args);

        // 如果使用rest方式以别名方式进行调用依赖ribbon负载均衡器 @LoadBalanced
        // @LoadBalanced就能让这个RestTemplate在请求时拥有客户端负载均衡的能力
    }

    // 解决RestTemplate 找不到原因 应该把restTemplate注册SpringBoot容器中 @bean
    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

这样虽然实现了rpc远程调用, 但是, 远程调用直接走的是ip地址, 实际上, 我们的调用地址应该从注册中心上获取
String url = "http://127.0.0.1:8000/getMember"应该改为String url = "http://api-provider/getMember", api-provider 为注册到注册中心的服务名称, 底层会把它转为IP地址.

    @RequestMapping("/getOrder")
    public String getOrder() {
        String url = "http://app-provider/getMember";
        String result = restTemplate.getForObject(url, String.class);
        System.out.println("调用服务result:" + result);
        return result;
    }

此外还有一个问题, 如果使用rest方式以别名方式进行调用, 需要依赖ribbon负载均衡器 @LoadBalanced,
@LoadBalanced就能让这个RestTemplate在请求时拥有客户端负载均衡的能力, rest底层是依赖ribbon的.

    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

@LoadBalanced注解用于实现负载均衡, 其实现负载均衡的原理是. 当服务注册到注册中心上时, 注册中心上包含该服务的ip地址和服务名称, 消费者根据服务名称拿到对应的IP地址, 饭后在本地使用ribbon来实现负载均衡策略, 一半策略就是轮训, 权重等.ribbon默认是轮训机制.

Eureka高可用原理

默认情况下Eureka是让服务注册中心,不注册自己

###因为该应用为注册中心,不会注册自己
    register-with-eureka: true
###不需要去注册中心上检索服务
    fetch-registry: true

Eureka高可用实际上将自己作为服务向其他服务注册中心注册自己,这样就可以形成一组相互注册的服务注册中心,从而实现服务清单的互相同步,达到高可用效果。

现在有两个服务8100和9100两个注册中心
在9100的服务上将8100注册到注册中心

###服务端口号
server:
  port: 9100
spring:
  application:
    name: app-eureka
eureka:
  client:
    serviceUrl:
    ##注册地址, 如果是超过两个, 除了自己的不写, 其他的都写
      defaultZone: http://${eureka.instance.hostname}:8100/eureka/
    ####因为自己是注册中心,是否需要将自己注册给自己的注册中心(集群的时候是需要是为true)
    register-with-eureka: true
    ###因为自己是注册中心, 不需要去检索服务信息
    fetch-registry: true

在8100的服务上将9100注册到注册中心

server:
  port: 8100
spring:
  application:
    name: app-eureka
eureka:
  client:
    serviceUrl:
    ##注册地址, 如果是超过两个, 除了自己的不写, 其他的都写
      defaultZone: http://${eureka.instance.hostname}:9100/eureka/
    ####因为自己是注册中心,是否需要将自己注册给自己的注册中心(集群的时候是需要是为true)
    register-with-eureka: true
    ###因为自己是注册中心, 不需要去检索服务信息
    fetch-registry: true

定义服务名称, 多个注册中心的名称一定要一样, 即都要是app-eureka

屏幕快照 2019-04-19 上午11.28.25.png

接下来启动消费者和生产者, 配置yml, 设置两台eureka注册中心的地址

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8100/eureka,http://localhost:9100/eureka

注意: 此时你会发现只有一台eureka服务, 9100或者8100有对应的消费者和生产者的信息, 并不是两台全都有. 类似于一主一备 当其中一台挂掉之后, 注册的信息会被自动转移到另外一台服务上.

上一篇下一篇

猜你喜欢

热点阅读