文章目录
服务注册(服务提供者):服务注册是指服务提供者启动时,将自己的信息注册到服务发现组件上的过程。服务提供者同时也可以是服务消费者。
服务发现(服务调用者/消费者):服务发现是指查询可用的微服务列表及其网络地址的机制。服务调用者在调用服务前会去服务注册中心查询可用的服务(服务发现)。服务调用者/服务消费者同时也可以是服务提供者。
服务注册中心:服务注册中心负责缓存服务提供者和服务调用者的信息,服务提供者在启动时会将自己的可用的服务注册到服务中心服务调用者/消费者在启动时会去注册中心拉取可用的服务列表到本地进行缓存。
1. Eureka
Spring Cloud Eureka是Spring Cloud Netflix微服务套件的一部分,基于Netflix Eureka做了二次封装,主要负责实现微服务架构中的服务治理功能。Spring Cloud Eureka是一个基于REST的服务,并且提供了基于Java的客户端组件,能够非常方便地将服务注册到Spring Cloud Eureka中进行统一管理。
服务治理是微服务架构中必不可少的一部分,和Eureka功能类似的还有阿里开源的Dubbo框架。服务治理必须要有一个注册中心,除了用Eureka作为注册中心外,还可以使用Consul、Etcd、ZooKeeper等作为服务的注册中心。
程序在运行的时候,会先去Eureka中去拉取服务列表,查看调用的服务在不在其中,有的话就拿到服务地址、端口等信息,然后调用。
注册中心的好处:服务调用者不需要知道有多少服务提供者,只需要关注注册中心即可。
为什么Eureka比ZooKeeper更适合作为注册中心?
主要是因为Eureka是基于AP原则构建的,而ZooKeeper是基于CP原则构建的。(CAP原则/定理)
1.1 Eureka Server(服务器端)与Client(客户端)
Eureka Server提供服务发现的能力,即它是一个注册中心,各个微服务启动时,会向Eureka Server注册自己的信息(如IP、端口、微服务名称等),Eureka Server会存储这些信息。
Eureka Client是一个Java客户端,用于简化与Eureka Server的交互。
Eureka Server与Client的交互方式如下:
- 各个微服务启动后,会周期性地(默认30s)向Eureka Server发送“心跳”以续约自己的“租期”(证明自己还活着,没有下线)
- 如果Eureka Server在一定时间内没有接收到某个微服务实例(客户端)的心跳,Eureka Server会注销该实例
- 默认情况下,Eureka Server同时也是Eureka Client。多个Eureka Server实例互相之间通过复制的方式来实现服务注册表中数据的同步
- Eureka Client会缓存服务注册表中的信息。这种方式有一定的优势:首先,微服务无需每次请求都查询Eureka Server,从而降低了Eureka Server的压力;其次,即使Eureka Server所有节点都挂掉(下线),服务调用者依然可以使用缓存中的信息找到服务提供者并完成调用。
1.2 服务提供者&服务调用者
服务提供者,其实是一个Eureka客户端,主要进行一下工作:
- 向Eureka Server(服务器端)注册服务
- 发送“心跳”给Eureka Server(服务器端)
- 从Eureka Server(服务器端)获取注册列表。当客户端注册到服务器时,它会提供一些关于自己的信息给服务器端,例如自己的主机名、IP、端口、健康检测连接等。
服务调用者,也是一个Eureka客户端,功能如下:
对于发布到Eureka服务器的服务,服务调用者可对其进行服务查找与调用,服务调用者是作为客户端存在的,其主要职责是发现与调用服务
注: 在实际情况中,有可能出现本身既是服务提供者,又是服务调用者的情况,例如在传统的企业三层架构中,服务层会调用数据访问层的接口进行数据操作,它本身也会提供服务给控制层使用。
2. 使用Eureka实现服务注册中心(暂时不完整)
第一步: 引入相关依赖,pom.xml如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</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> 第二步:在application.properies配置文件中加入以下内容:
server.port = 8081
#
eureka.instance.hostname = eureka-server1
# registerWithEureka 表示是否向Eureka Server注册自己,默认是true。
# 但本例的Eureka是注册中心,所以设置为false,代表不向注册中心注册自己
eureka.client.registerWithEureka=false
# fetchRegistry 表示是否从Eureka Server获取注册信息,默认为true。
# 但本例的Eureka Server是单点的,不需要同步数据,所以设置为false.
eureka.client.fetchRegistry=true
# serviceUrl.defaultZone 表示查询和注册服务的地址,多个地址之间用“,”分隔
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
第三步:修改启动类内容如下:(@EnableEurekaServer声明这是一个Eureka服务器)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
//启用注册中心
@EnableEurekaServer
@SpringBootApplication
public class EurekaServer1Application {
public static void main(String[] args) {
SpringApplication.run(EurekaServer1Application.class, args);
}
}第四步:打开浏览器验证,输入http://localhost:8081
3. 注册微服务到Eureka Server(服务提供者)
引入相关依赖,pom.xml主要内容如下:
<dependencies>
<!--eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>- application.properties文件如下:
#服务端口
server.port=8082
#应用名称
spring.application.name=first-service-provider
#服务实例的主机名称
eureka.instance.hostname=localhost
#注册到此服务器
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/- 编写服务代码:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class userController {
@RequestMapping(value="/hello/{name}")
public String sayHello(@PathVariable("name") String name){
return "Hello"+name;
}
}- 启动类(@EnableEurekaClient声明这是一个Eureka客户端):
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
//@EnableEurekaClient声明这是一个Eureka客户端
@EnableEurekaClient
//@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
@SpringBootApplication
public class app{
public static void main(String[] args)
{
SpringApplication.run(app.class, args);
}
}4. 从注册中心拉取(调用)微服务进行消费(服务调用者)
- 引入相关依赖,pom.xml主要内容如下:
<dependencies>
<!-- -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
</dependencies>- application.properties配置文件:
#服务端口
server.port=8083
#应用名称
spring.application.name=first-service-consumer
#服务实例的主机名称
eureka.instance.hostname=localhost
#注册到此服务器
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/- 服务调用代码:
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class helloController {
public RestTemplate getRestTemplate()
{
return new RestTemplate();
}
@RequestMapping(value="/router" )//produces=MediaType.JSON_UTF_8
public String router()
{
RestTemplate rstl=getRestTemplate();
String json=rstl.getForObject("http://first-service-provider/hello/?wangxingze", String.class);
return json;
}
}- 启动类和第二步的服务消费者一样
第四步:启动测试,步骤如下:
- 启动Eureka Server
- 启动服务提供者
- 启动服务调用者