目录
一、服务中的提供者与消费者
二、Eureka工作流程
三、搭建Eureka服务
四、服务拉取
五、总结
1.搭建EurekaServer
2.服务注册
3.服务发现
一、服务中的提供者与消费者
服务提供者:一次业务中,被其他微服务调用的服务。即提供接口给其他微服务。
服务消费者:一次业务中,调用其他微服务的服务。即调用其他微服务提供的接口。
二、Eureka工作流程
我们在服务调用会出现一些问题,比如服务消费者该如何获取服务提供者的地址信息?如果有多个服务提供者,消费者该如何选择?消费者如何得知服务提供者的健康状态?
Eureka的工作流程:
Eureka分为服务端和客户端,服务端主要是用作注册中心,客户端用于放置服务消费者和服务提供者。
首先,Eureka注册中心首先将服务端的所有服务提供者和服务消费者注册并记录起来,但是会根据类型进行区分,这一步就是完成了登记注册功能。
第二步,服务消费者要想调用服务提供者提供的接口,就要先访问注册中心,从注册中心中拉取所有的服务提供者然后通过负载均衡选择一个服务提供者,然后就要进行远程调用服务提供者的接口。
那么,消费者如何得知服务提供者的健康状态?
其实,服务提供者会对注册中心进行心跳续约的策略,要是有某些时间注册中心接受不到服务提供者的心跳提示,即他不存活了,就可以判断其已死亡,一次删除其记录,服务消费者也不会再查询到。
消费者该如何获取服务提供者具体信息?
服务提供者启动时向eureka注册自己的信息,eureka保存这些信息,消费者根据服务名称向eureka拉取提供者信息
如果有多个服务提供者,消费者该如何选择?
服务消费者利用负载均衡算法,从服务列表中挑选一个消费者
如何感知服务提供者健康状态?
服务提供者会每隔30秒向EurekaServer发送心跳请求,报告健康状态,eureka会更新记录服务列表信息,心跳不正常会被剔除,消费者就可以拉取到最新的信息。
三、搭建Eureka服务
首先,我们创建一个普通Javamaven项目,作为父工程:
可以将创建好的项目中的src目录删除,因为我们并不会在在父工程中编写代码逻辑,只作为父工程处理。
然后在父工程中创建新模块(springboot):
相同思路,创建一个order-service和eureka-server(这个选依赖的时候,选择Eureka Server)。
创建后的项目目录:
依赖信息:
在eureka-server的启动类上加上注解:
在eureka-server中创建资源文件夹,并配置application.yaml:
server: port: 12211 #端口号spring: application: name: eurekaserver #eureka的服务名称eureka: service-url: #eureka的地址信息 defaultZone: http://localhost:12211/eureka client: register-with-eureka: false # 表示不向注册中心注册 fetch-registry: false # 由于注册中心的职责就是维护服务实例,所以它不需要去检索服务
启动启动类,并访问地址:localhost:12211
从上面的红色区域,我们就能看到,注册到eureka中的配置。
对于eureka-server的配置:我们总体就有三个步骤:
1.引入依赖。2.加注解。3.配置文件。
接下来,我们进行注册user-service和order-service:
两个步骤操作一样,因此,只展示其中一个:
引入依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
配置application.yaml:
server: port: 8081 #端口号spring: application: name: orderservice #eureka的服务名称eureka: client: service-url: #eureka的地址信息 defaultZone: http://localhost:12211/eureka
然后启动即可:
再次访问:
注册的实例都已经配置上了
另外,我们可以将user-service多次启动,模拟多实例部署,但为了避免端口冲突,需要修改端口设置:
四、服务拉取
基于上述配置,我们通过order-service通过调用user-service来完成获取用户信息的功能。
首先,在order-service的启动类中加上一个bean,加上@LoadBlanced用于指示负载均衡:
@Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); }
然后我们在order-service中配置一个controller:
package com.order.orderservice.controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;@RestControllerpublic class MyController { @Resource private RestTemplate restTemplate; @RequestMapping("/getOrder") @ResponseBody public String getOrder(){ String url="http://userservice/getUser"; String s = restTemplate.getForObject(url, String.class); return "成功得到用户"+s; }}
在application.yaml中添加配置:
server: port: 8081 #端口号spring: application: name: orderservice #eureka的服务名称eureka: client: service-url: #eureka的地址信息 defaultZone: http://localhost:12211/eurekahttp: maxTotal: 100 #最大连接数 defaultMaxPerRoute: 20 #并发数 connectTimeout: 1000 #创建连接的最长时间 connectionRequestTimeout: 500 #从连接池中获取到连接的最长时间 socketTimeout: 10000 #数据传输的最长时间 staleConnectionCheckEnabled: true #提交请求前测试连接是否可用 validateAfterInactivity: 3000000 #可用空闲连接过期时间,重用空闲连接时会先检查是否空闲时间超过这个时间,如果超过,释放socket重新建立
再在user-service中写一个controller和对应的方法:
package com.user.userservice.controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class UserController { @RequestMapping("/getUser") @ResponseBody public String getUser(){ return "张三"; }}
通过调用order-service中的请求,order-service再通过注册中心请求user-service中的相关内容,即可获取。
心细的人就会发现,我们写URL的时候并没有指明端口号,而是给出的服务名称,因为这些服务都是注册到注册中心的,因此,我们可以直接用名称来代替。
五、总结
1.搭建EurekaServer
引入eureka-server依赖
添加@EnableEurekaServer注解
在application.yml中配置eureka地址
2.服务注册
引入eureka-client依赖
在application.yml中配置eureka地址
3.服务发现
引入eureka-client依赖
在application.yml中配置eureka地址
给RestTemplate添加@LoadBalanced注解
用服务提供者的服务名称远程调用