- 前言
- 环境准备
- 代码准备和说明
- 第一节 将服务注册到nacos
- 第二节 服务调用
- 1. 从nacos获取服务列表,手动调用
- 2. Ribbon负载均衡
- 2.1 如何添加负载均衡
- 2.2更换负载均衡策略
- 3. 基于feign的远程调用
- 3.1 如何使用Feign
基于spring cloud alibaba的架构,如何实现服务调用。
本章代码已分享至Gtiee :https://gitee.com/lengcz/springcloudalibaba01.git
环境准备- 需要先安装和启动nacos。如果未安装,请见:nacos基础(2):下载安装启动和排错
- common 公共模块,存放实体类等信息,公共工具等信息
- order 订单模块 订单业务
- product 商品模块 商品业务
- user 用户模块
需要将几个模块都注册到nacos
- 导入依赖
com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery
- 主类上启动服务发现的注解 @EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient //启动服务发现
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
- 配置nacos注册中心的地址
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
- 启动服务,可以发现(微服务名称为spring.application.name)
使用DiscoveryClient从nacos列表中获取服务实例,并手动调用
ServiceInstance instance=discoveryClient.getInstances("server-product").get(0);
Product product = restTemplate.getForObject("http://"+instance.getHost()+":"+instance.getPort()+"/product/" + pid, Product.class);
log.info("查询到的商品内容:" + JSON.toJSONString(product));
2. Ribbon负载均衡
2.1 如何添加负载均衡
- 给RestTemplate添加注解@LoadBalanced
@Bean
@LoadBalanced //启动负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
- 修改调用代码
//server-product为被调用的服务名
Product product = restTemplate.getForObject("http://server-product/product/" + pid, Product.class);
- 启动两个product服务,可以发现nacos控制台有两个实例
4. 重启order多次请求创建订单接口,观察日志,可以看到product的两个服务实例都有被调用。
需要在调用方配置此项
#配置负载均衡器 server-product.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule3. 基于feign的远程调用
Feign是Spring Cloud提供的一种声明式的伪http客户端,它调用远程服务就像调用本地服务一样简单,只需要创建一个接口并添加注解即可。
nacos很好的兼容了Feign,Feign默认集成了Ribbon,所以在nacos下使用Feign默认就实现了负载均衡。
- 添加依赖
org.springframework.cloud spring-cloud-starter-openfeign
- 在主类开启Feign的客户端@EnableFeignClients
@SpringBootApplication
@EnableDiscoveryClient //启动服务发现
@EnableFeignClients //开启feign的客户端
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Bean
@LoadBalanced //启动负载均衡
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
- 在order模块里定义ProductService的接口
@FeignClient(value="server-product") //指向server-product服务
public interface ProductService {
@RequestMapping("/product/{pid}")
Product findById(@PathVariable Integer pid);
}
- 使用这个Feign客户端接口
@Autowired
private ProductService productService;
@GetMapping("/order/prod/{pid}")
public Order order(@PathVariable Integer pid) {
log.info("调用商品服务,调用商品微服务查询此商品");
Product product = productService.findById(pid);
log.info("查询到的商品内容:" + JSON.toJSONString(product));
Order order = new Order();
order.setUid(1);
order.setUsername("测试");
order.setPid(pid);
order.setPrice(product.getPrice());
order.setPname(product.getPname());
order.setNumber(1);
orderService.createOrder(order);
log.info("用户下单成功,订单信息为:" + JSON.toJSON(order));
return order;
}
- 请求测试,发现同样可以请求到远程的product服务。



