服务治理和服务发现——Eureka

按照现今互联网的开发,高井发、大数据、快响应己经是普遍的要求。为了支撑这样的需求,互联网系统也开始引入分布式的开发。为了实现分式的开发,Spring推出了一套组件,那就是SpringCloud。

当前SpringCloud已经成为构建分布式微服务的热门技术。它并不是自己独自造轮子,而是将目前各家公司已经开发好的、经过实践考验较为成熟的技术组合起来,并且通过SpringBoot风格进行再次封装,从而屏敲掉了复杂的配置和实现原理,为开发者提供了一套简单易懂、易部署和维护的分布式系统开发包。

分布式是非常复杂的,在大部分情况下非超大型企业很难开发自己的分布式框架,因为研发成本较高,而且周期很长,这时SpringCloud就为这些企业提供了一个开源井且免费的解决方案。首先,SpringCloud是一套组件,可以细分为多种组件,如服务发现、配置中心、消息总线、负载均衡、断路器和数据监控等。

服务治理和服务发现——Eureka

SpringCloud中主要是使用NtfliEureka作为服务治理的,SpringCloud对其进行了一次封装,使得开发者可以以SpringBoot的风格使用它,这样就为它的使用带来了极大的便利。通过服务注册将单个微服务节点注册给服务治理中心,这样服务治理中心可以治理单个微服务节点。服务发现则是微服务节点可以对服务治理中心发送消息,使得服务治理中心可以将新的微服务节点纳入管理。

配置服务治理的节点

SpringCloud的服务治理是使用Netflix的Eureka作为服务治理器的,它是我们构建SpringCloud分布式最为核心和最为基础的模块,它的作用是注册和发现各个SpringBoot微服务,并且提供监控和管理的功能。搭建服务治理节点并不是很复杂,甚至可以说很简单,为此先搭建一个注册中心。

引入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    <dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

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

这里的引入依赖不建议直接复制粘贴,建议使用springio去构建,而且必须注意的是,SpringCloud的版本要和SpringBoot的版本相符合,版本对应从:https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies。中去寻找。

启动Eureka

1
2
3
4
5
6
7
8
9
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

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

}

这里仅仅只需要加上一个注解便可以了。

配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
spring:
application:
name: server


server:
port: 7001
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://localhost:7001/eureka/
  • 属性eureka.client.register-with-eureka配置为false,是因为在默认的情况下,项目会自动地查找服务治理中心去注册。这里目自身就是服务治理中心,所以取消掉注册服务中心。
  • 属性Eureka.client.fetch-registry配置为false,它是一个检索服务的功能,因为服务治理中心是维护服务实例的,所以也不需要这个功能,即设置为了false。
  • 属性eureka.client.serviceUrl.defaultZone代表服务中心域,将来可以提供给别的微服务注册。后面的微服务还会使用到它。

接下来,我们便打开http://localhost:7001/eureka/端口看一看吧。

服务发现

注册中心配置好了之后,我们来制作一个服务发现者,他可以是用户这种消费者,也可以是生产者,但仍然需要建立一个新的模块。

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

值得注意的是,服务发现者并不用加注解,便可以直接使用。

但同样的,也需要配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
server:
port: 9001

spring:
application:
name: product
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/
instance:
prefer-ip-address: true

加上prefer-ip-address,注册ip的时候使用服务的ip地址。

这里使用了9001端口,而应用名称为product,这个微服务名称将会注册给服务治理中心。而这个应用就会作为这个名称为RODUCTC注意大写〉服务的一个节点。治理客户端服务域则是通过属性eureka.client.serviceUrl.defaultZone进行配置的,它也配置了服务治理中心同样的地址,这样它就能够注册到之前所配置的服务治理中心。假设服务治理中心已经开启,然后启动这个产品微服务,再次看到服务治理中心的网址,就可以看到注册成功的页面。

同样的,一个注册中心也会支持多个发现者去注册,我们便再建立一个模块User去注册吧。

看到这里可能很多人会有一些疑问。它们为什么要这样做?其实它很简单,在一些大型的网站中,就可以通过这种方式一步一步增加新的模块。而不用等所有模块都建好了,在上线部署。

高可用的服务治理中心

Eureka Server 的高可用实际上就是将自己作为服务想其它服务注册中心注册自己,这样就形成了一组互相注册的服务中心。

这样如果出现,如果有一个服务中心突然发生故障的话,那么其他的服务中心也可以支持消费者的使用。

要实施这样的功能非常的简单。

配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
spring:
application:
name: server


server:
port: 7001
eureka:
instance:
hostname: localhost
client:
# register-with-eureka: false
# fetch-registry: false
service-url:
defaultZone: http://localhost:7002/eureka/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
spring:
application:
name: server



server:
port: 7002
eureka:
instance:
hostname: localhost
client:
# register-with-eureka: false
# fetch-registry: false
service-url:
defaultZone: http://localhost:7001/eureka/

那就是将两个服务中心互相定位到对方的地址,这样他们就会将彼此注册进去。

同时,我们也要将消费者的服务地址,加上这两处注册中心。

1
2
3
4
5
6
7
8
9
10
11
12
server:
port: 9001

spring:
application:
name: product
eureka:
client:
service-url:
defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/
instance:
prefer-ip-address: true

我们可以继续打开之前的网址,查看

这样一个完整的服务中心就完成了。而且,Eureka还能够自我的实现负载均衡,那就是利用Ribbon和Feign。相同的服务可以交替被消费者访问,大大的减少数据流对单个业务端的压力。