功能性的网站建设,北京餐饮品牌设计公司,wordpress关键,定制网站制作公司怎么样文章目录 一、什么是负载均衡二、Ribbon 负载均衡2.1 Ribbon 使用2.2 Ribbon 实现原理 (★)2.3 Ribbon 负载均衡算法 三、Feign 远程调用3.1 Feign 简述3.2 Feign 的集成3.3 Feign 实现原理 (★) 一、什么是负载均衡
《服务治理#xff1a;Nacos 注册中心》 末尾提到了负载均… 文章目录 一、什么是负载均衡二、Ribbon 负载均衡2.1 Ribbon 使用2.2 Ribbon 实现原理 (★)2.3 Ribbon 负载均衡算法 三、Feign 远程调用3.1 Feign 简述3.2 Feign 的集成3.3 Feign 实现原理 (★) 一、什么是负载均衡
《服务治理Nacos 注册中心》 末尾提到了负载均衡那什么是负载均衡呢 负载均衡就是将负载⼯作任务访问请求进⾏分摊到多个操作单元服务器组件上进行执行。 根据负载均衡发⽣位置的不同⼀般分为 服务端负载均衡 和 客户端负载均衡。
服务端负载均衡指的是发生在服务提供者一方比如常见的 Nginx 负载均衡。客户端负载均衡指的是发生在服务请求的一方也就是在发送请求之前已经选好了由哪个实例处理请求。 注在微服务调⽤关系中⼀般会选择客户端负载均衡也就是在服务调用的一方来决定服务由哪个提供者执行。 二、Ribbon 负载均衡
2.1 Ribbon 使用
Ribbon 是 Spring Cloud 的⼀个组件 它可以让我们使用一个注解就能轻松的搞定负载均衡。
1、在 RestTemplate 的生成方法上添加 LoadBalanced 注解
Bean
LoadBalanced // 表示继承Ribbon进行负载均衡
public RestTemplate restTemplate() {return new RestTemplate();
}2、修改服务调用的方法
Service
Slf4j
public class OrderServiceImpl implements OrderService {Autowiredprivate OrderDao orderDao;Autowiredprivate RestTemplate restTemplate;Overridepublic Order createOrder(Long productId, Long userId) {log.info(接收到{}号商品的下单请求接下来调⽤商品微服务查询此商品信息, productId);// 远程调⽤商品微服务查询商品信息String url http://product-service/product/ productId;log.info(服务器地址: {}, url);// 远程调⽤商品微服务,查询商品信息Product product restTemplate.getForObject(url, Product.class);log.info(查询到{}号商品的信息内容是:{}, productId, JSON.toJSONString(product));// 创建订单并保存Order order new Order();order.setUid(userId);order.setUsername(安秀岩);order.setPid(productId);order.setName(product.getName());order.setPrice(product.getPrice());order.setNumber(1);orderDao.save(order);log.info(创建订单成功订单信息为{}, JSON.toJSONString(order));return order;}
}对比以下两种方式差异显著 //⾃定义规则实现随机挑选服务ListServiceInstance instances discoveryClient.getInstances(product-service);int index new Random().nextInt(instances.size());ServiceInstance instance instances.get(index);String url instance.getHost() : instance.getPort();log.info(从nacos中获取到的微服务地址为: url);简化成了以下一行// Ribbon 直接使用需要远程调用的服务名称即可
String url http://product-service/;那 Ribbon 底层原理又是什么呢为什么可以使用服务名称就能远程调用该服务呢 2.2 Ribbon 实现原理 (★)
现假设两个商品服务做集群向Nacos注册的IP分别是192.168.10.1118081192.168.10.1128081
step1当使用 RestTemplate 远程访问时http://product-service/product/1 首先会将服务名称截取出来 product-service step2并在本地缓存列表中获取到服务的 IP 集合即{{192.168.10.111:8081}, {192.168.10.112:8081}}。 step3根据内部配置的 负载均衡算法从集合中选取其中一个IP地址如192.168.10.112:8081 step4将原来的 url 替换成 http://192.168.10.112:8081/product/1最终通过 RestTemplate 发起请求。 2.3 Ribbon 负载均衡算法
Ribbon 内置了多种负载均衡策略内部负载均衡的顶级接口为 com.netflix.loadbalancer.IRule具体的负载策略如下图所示: 可以通过修改配置来调整 Ribbon 的负载均衡策略如在 order-server 项目的 application.yml 中增加如下配置
product-service: # 调⽤的提供者的名称ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule三、Feign 远程调用
3.1 Feign 简述
为什么要使用 feign 呢原来的调用的方式 String url http://product-service/product/ productId; 是固定的字符串做拼接不够灵活而且还存在 productId 参数校验问题等因此 Feign 可解决这个问题。 Feign 是 Spring Cloud 提供的⼀个声明式的伪 Http 客户端它使得调用远程服务就像调用本地服务一样简单只需要创建一个接口并添加一个注解即可。Nacos 很好的兼容了 FeignFeign 默认集成了 Ribbon所以在 Nacos 下使用 Fegin 默认就实现了负载均衡的效果。 3.2 Feign 的集成
1、在shop-order-server项⽬的pom文件加入Fegin的依赖
dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId
/dependency2、在启动类上添加 Fegin 的扫描注解 EnableFeignClients注意扫描路径(默认扫描当前包及其子包)
SpringBootApplication
EnableDiscoveryClient
EnableFeignClients // 会扫描当包及其子包下贴有FeignClient注解的接口
public class OrderServer {public static void main(String[] args) {SpringApplication.run(ProductApplication .class, args);}
}3、在 shop-order-server 项目中新增接口 ProductFeignApi 和该接口的容错类 ProductFeignFallback
FeignClient(name product-service, fallback ProductFeignFallback.class)
// 远程调用服务名称fallback 指定返回兜底数据的类的字节码即服务挂起时的降级类方法
public interface ProductFeignApi {RequestMapping(/product/{pid})// 路径要与 ProductController 的接口保持一致Product findByPid(PathVariable(pid) Long pid);
}Component // 该类的作用是返回兜底数据以防 “服务器雪崩”
public class ProductFeignFallback implements ProductFeignApi {Overridepublic Product findByPid(Long pid) {System.out.println(返回兜底数据);return new Product();}
}4、修改服务调用的方法
Service
Slf4j
public class OrderServiceImpl implements OrderService {Autowiredprivate OrderDao orderDao;Autowiredprivate ProductFeignApi productFeignApi;Overridepublic Order createOrderFeign(Long productId, Long userId) {// feign 调用Product product productFeignApi.findByPid(productId);log.info(查询到{}号商品的信息内容是:{}, productId, JSON.toJSONString(product));// 创建订单并保存Order order new Order();order.setUid(userId);order.setUsername(叩丁狼教育);order.setPid(productId);order.setName(product.getName());order.setPrice(product.getPrice());order.setNumber(1);orderDao.save(order);log.info(创建订单成功订单信息为{}, JSON.toJSONString(order));return order;}
}3.3 Feign 实现原理 (★)
Feign 实现的原理是基于动态代理和反射技术并且内部还是使用 RestTemplate 实现的具体详细流程如下 文章参考Java微服务商城高并发秒杀项目实战|Spring Cloud Alibaba真实项目实战商城双11秒杀高并发消息支付分布式事物Seata