SpringCloud-2-服务注册与发现

1.SpringCloud Eureka

1.1 简单微服务架构

上图中的服务注册和发现在SpringCloud中用的就是:Eureka

1.2 简单介绍
  1. 基于Netflix Eureka做了二次封装
  2. 主要由两个组件组成: -Eureka Server(注册中心) -Eureka Client(服务中心)

2.Eureka Server

2.1 简介
  1. 注册中心好比老师手中名单 记录着所有同学名字 点名时候,根据手册名单
  2. 注册中心记录着所有应用的信息和状态(应用名,所在服务器,是否正常工作),在微服务架构中,我们把应用叫做服务
  3. 由图所知:服务中心就是找到服务
    2.2 创建Eureka Server应用




项目创建后我们不着急启动,先看下pom.xml文件:
SpringBoot的版本和SpringCloud版本如下所示:

我们如何知道SpringBoot版本和SpringCloud的版本匹配呢?我们进入SpringCloud官网:https://spring.io/

将pom.xml中设置成统一匹配的:

关于版本的具体问题,请参考:https://blog.csdn.net/sinat_33889619/article/details/89403796

2.3 启动Eureka Server

1.启动时候报错:没有出现注册中心界面

2.添加@EnableEurekaServer注解

1
2
3
4
5
6
7
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}

重启发现出现注册中心的界面:

3.启动时候虽然可以访问,但是出现了下面的错误:

1
com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server

这是因为此应用不仅是一个server端同时也是一个client端。他也需要找到一个注册中心,把自己注册上去。我们配置一下他注册的地址:就是往自己身上注册。

点击service-url进入:EurekaClientConfigBean

1
2
3
4
5
6
7
public void setServiceUrl(Map<String, String> serviceUrl) {
this.serviceUrl = serviceUrl;
}
```
serviceUrl是一个map的key为:defaultZone

eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka/

1
2
3
4
5
6
7
重启项目时候:注册时候是心跳检测注册,刚开始会有错误,等一会就可以了,如下已经注册上:
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/37.png)
由于注册的Application的名字为:UNKNOWN 我们修改此应用的名字,添加如下配置:

spring:
application:
name: eureka

1
2
3
4
5
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/38.png)
4.由于此应用本来就是一个注册中心,自己注册到自己不出现在注册实例中:添加如下配置:register-with-eureka: false

eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka/
register-with-eureka: false

1
2
3
4
5
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/39.png)
5.由于我们后面很多应用都是8080端口,所以我们修改注册中心的地址为默认端口:8761

eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
register-with-eureka: false
spring:
application:
name: eureka
server:
port: 8761

1
2
3
4
5
6
#### 3.Eureka Client(服务注册)
##### 3.1 启用注册中心
注册中心为了方便不需要每次在idea中启动,我们应该打成jar包,然后通过命令在后台启用。进入eureka的根目录,执行:

mvn clean package

1
2
3
生成后端启动:

nohup java -jar eureka-0.0.1-SNAPSHOT.jar &

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
##### 3.2 创建Eureka Client应用
1. 创建应用
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/25.png)
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/40.png)
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/41.png)
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/42.png)
删除不需要的文件:
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/43.png)
client端和server端的版本保持一致:
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/44.png)
2. 添加注册中心地址:

eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: client

1
2
3
4
5
6
7
8
3. 开启服务注册
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/45.png)
有时候启动报错:

Invocation of destroy method failed on bean with name ‘scopedTarget.eurekaClient’: org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name ‘eurekaInstanceConfigBean’: Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)

1
2
3
4
解决:添加web依赖


org.springframework.boot
spring-boot-starter-web

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
4. 查看是否已经注册
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/46.png)
5. 如果不停的启动client端,会在注册中心出现:
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/47.png)
client<--->server端是采用心跳的机制,server端会不听的检查client端是否存活上线,在一定时间会统计出client端的上线率,当低于某个比例时候 会报出以上警告,在开发环境我们可以把它关掉(在server端里面配置文件加上:)
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/48.png)
#### 4.Eureka高可用
##### 4.1 Eureka单节点
1. 上面的Eureka是单点的,如果挂了的话 所以client端服务都不可以运行了
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/49.png)
##### 4.2 Eureka多节点之间互相注册,但是client注册到其中一个Eureka
1. 让Eureka Server开启两个,之间互相注册,虽然client只在server1上注册,但是会把client注册也会拷贝到server2注册
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/50.png)
2. 开启两个Eureka Server端口分别为:8761、8762
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/51.png)
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/52.png)
以端口来区分:Eureka1:8761 Eureka2:8762
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/53.png)
![](https://raw.githubusercontent.com/startshineye/img/master/2019/04/54.png)
注释掉yml中原来端口:

//server:
//port: 8761
```


启动


启动

访问:http://localhost:8762 我们可以看到之前注册到8761的服务也注册到8762上了,这是因为:8761和8762之间互相注册了。互相注册后,他们之上的信息有所交换。

4.3 Eureka1挂了 重启Eureka2和client

此时我们重启client和Eureka2时候,我们发现在Eureka2上没有发现client,这个时候我们就需要把client注册到Eureka1和Eureka2上才行。

4.4 Eureka包含3个以上

有时候我们服务比较多,并且需要的注册中心也比较多,也就是Eureka Server比较多,我们该怎么做呢?

5.Eureka总结

6.分布式下服务注册的地位和原理

6.1 传统服务发现

传统服务A要找到服务B,是通过在服务A中配置B的地址从而找到B,在分布式系统中,各个系统之间是不共享内存的,如下A服务如果要找到B服务就需要,并且B服务是分布式集群的,B中的服务器是不确定多少台,在云服务时代,服务器根据压力容量可能会动态改变,此时如果还是在A里面配置多个B节点注册中心地址不可取。

6.2 注册中心服务发现

  1. 类似于注册中心就是个代理,需要找谁就找谁
  2. 通过以上可以知道注册中心 是分布式服务中最重要的基础部分。

  3. A是如何通过”注册中心”找导服务B的呢?
    客户端发起:A通过注册中心可以找到需要B,从中只需要找到一个B(通过轮训、hash等负载均衡机制等方式)
    服务端发现:通过代理的方式

6.3 思考
  1. SpringCloud是提供java应用程序之间的服务注册,那么如果有些服务是c/php/node.js写的服务,该怎样取进行服务发现和注册了,SpringCloud的Eureka使用客户端发现方式进行服务发现,SpringCloud是一个强大的我服务体系,但是是纯java的,山本大叔倡导轻量级的方式去实现微服务,所以采用了Http Restful API的方式,并且提供了Restful API接口让其他不同语言的服务区实现接口,达到服务注册。
  2. 微服务具有异构特点:各个服务间可以用不同语言,每个服务可以根据需要选择不通的数据库
毕业于<br>相信技术可以改变人与人之间的生活<br>码农一枚