1. 服务的远程调用
??通过 RestTemplate 远程调用其它服务的请求
??在启动方法中将 RestTempate 对象注入到 Spring 容器中
package cn.peng.order;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@MapperScan("cn.peng.order.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
??实现调用其他服务的代码
package cn.itcast.order.web;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import cn.itcast.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@RestController
@RequestMapping("order")
public class OrderController {
@Autowired
private OrderService orderService;
@Resource
private RestTemplate restTemplate;
@GetMapping("{orderId}")
public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
Order order = orderService.queryOrderById(orderId);
String url = "http://localhost:8081/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
order.setUser(user);
return order;
}
}
2. Eureka 与 Ribbon
(1) 服务的提供者与消费者
- 服务提供者:暴露接口给其它微服务调用
- 服务消费者:调用其它微服务提供的接口
- 一个服务既可以是服务的提供者,也可以是服务的消费者,它们是相对的
(2) eureka 的作用
-
消费者该如何获取服务提供者具体信息?
- 服务提供者启动时向 eureka 注册自己的信息
- eureka 保存这些信息
- 消费者根据据服务名称向 eureka 拉取提供者信息
??服务消费者利用负载均衡算法,从服务列表中挑选一个
-
消费者如何感知服务提供者健康状况?
- 服务提供者会每隔 30 秒向 EurekaServer 发送心跳请求,报告健康状况
- eureka 会更新记录服务列表信息,心跳不正常会被剔除
- 消费者就可以拉取到最新的消息
??在微服务中,eureka 有两种角色:
- EurekaServer:eureka 的服务端,注册中心。主要是记录服务信息和心跳监控
- EurekaClient:eureka 的客户端
??provider:服务的提供者:注册自己的信息到 EurekaServer 中,每隔 30 秒向 EurekaServer 发送心跳 ??consumer:服务的消费者:根据服务名称从 EurekaServer 拉取服务列表,基于服务列表做负载均衡,选中一个微服务后发起远程调用
(3) 搭建 eureka 服务的注册中心
??创建一个新的微服务 eureka-server 来作为 eureka 的注册中心
??引入 eureka 服务端的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
??编写 eureka 微服务的启动类
package com.peng.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
??编写 application.yml 的配置文件
server:
port: 10086
spring:
application:
name: eurekaserver
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
??然后启动微服务,在浏览器访问 http://localhost:10086/,看到下图就成功了
注意:启动这个 eureka 微服务可能会报错,错误是因为启动时要做服务拉取,而 eureka 尚未完全启动导致的,对服务本身并无影响,可以忽略
(4) eureka 的服务注册
??将微服务注册到 eureka 注册中心
??引入 eureka 客户端的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
??在 application.yml 中添加注册到 eureka 的配置信息
spring:
application:
name: userservice
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
(5) 服务的拉取和负载均衡
??把所有服务都注册到 eureka 后,我们就可以通过服务名称来进行远程调用了,并且可以实现负载均衡
(6) 自定义负载均衡策略
??Ribbon 默认的负载均衡策略是轮询,我们可以通过两种方式修改负载均衡策略
- 代码方式:在启动类或配置类中重新注入一个新的 IRule
@Bean
public IRule randomRule() {
return new RandomRule();
}
- 配置文件方式:在 application.yml 文件中添加配置,修改负载均衡策略
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
(7) 配置 Ribbon 饥饿加载
??Ribbon 默认是采用懒加载,即第一次访问时才会去创建 LoadBalanceClient,请求时间会很长。 ??而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:
ribbon:
eager-load:
enabled: true
clients: userservice
3. Nacos 注册中心
??Nacos 相比 eureka 功能更加丰富
(1) docker 安装 nacos
??拉去 nacos 镜像
docker pull nacos/nacos-server
??创建 nacos 容器,配置环境为单机模式
docker run -di --name=nacos -p 8848:8848 --env MODE=standalone nacos/nacos-server
??然后阿里云打开 8848 端口,浏览器访问:http://39.99.149.140:8848/nacos/index.html,账号和密码都是 nacos
(2) 将服务注册到 nacos 中
??Nacos 是 SpringCloudAlibaba 的组件,而 SpringCloudAlibaba 也遵循 SpringCloud 中定义的服务注册、服务发现规范。因此使用 Nacos 和使用 Eureka 对于微服务来说,并没有太大区别。
主要差异在于:
??引入依赖:在父工程的 pom 文件中的<dependencyManagement> 中引入 SpringCloudAlibaba 的依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
??然后在应用到 nacos 的微服务中引入 nacos 的依赖。不要忘记去掉 eureka 的依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
??在 application.yml 中添加注册到 nacos 的地址,注意去掉 eureka 的注册地址
spring:
cloud:
nacos:
server-addr: 39.99.149.140:8848
(3) Nacos 与 eureka 的区别
??Nacos 的服务实例分为两种类型:
??配置一个服务实例为永久实例:
spring:
cloud:
nacos:
discovery:
ephemeral: false
??Nacos 和 Eureka 整体结构类似,服务注册、服务拉取、心跳等待,但是也存在一些差异:
??Nacos 与 eureka 的共同点
- 都支持服务注册和服务拉取
- 都支持服务提供者心跳方式做健康检测
??Nacos 与 Eureka 的区别
- Nacos 支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
- 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
- Nacos 支持服务列表变更的消息推送模式,服务列表更新更及时
|