7. SpringCloudAlibaba 实践笔记:服务治理项目集成

搭建 Nacos 注册中心

下载和解压

启动和访问

启动Nacos之后,在浏览器中输入链接http://localhost:8848/nacos 来访问Nacos的管理界面,默认的用户名和密码都是Nacos。

进入到Nacos的服务管理-服务列表菜单
image

在Nacos的服务管理-服务列表菜单下还没有任何服务,接下来对项目进行改造,与 Nacos 集成。
image
在 Nacos 的服务管理-服务列表菜单下还没有任何服务,接下来对项目进行改造,与 Nacos 集成。

注册中心集成

用户微服务集成

引入依赖

在用户微服务的 pom.xml 文件中添加 nacos 的服务注册与发现依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

应用配置修改

在用户微服务的 resources 目录下的 application.yml 文件中添加 Nacos 注册中心的服务地址配置。

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

启动类修改

在启动类添加 @EnableDiscoveryClient 注解

@SpringBootApplication
@EnableTransactionManagement(proxyTargetClass = true)
@MapperScan(value = { "io.binghe.shop.user.mapper" })
@EnableDiscoveryClient
public class UserStarter {

    public static void main(String[] args){
        SpringApplication.run(UserStarter.class, args);
    }
}

查看改造结果

启动用户微服务,并刷新 Nacos 页面。
image

其他服务集成

以相同的方式改造商品微服务和订单微服务。

服务发现配置

用户微服务和商品微服务作为服务的提供者,订单微服务作为服务的消费者,如果要实现服务的发现功能,我们还需要对订单微服务的代码进行改造。将订单微服务中硬编码的用户微服务和商品微服务的IP地址和端口号修改成从Nacos中获取。

注入服务发现类

在 shop-order 的 OrderServiceImpl 类注入 DiscoveryClient 类的对象

@Autowired
private DiscoveryClient discoveryClient;

创建动态服务地址方法

在 shop-order 的 OrderServiceImpl 类创建一个从Nacos中通过服务名称获取IP和端口号的方法getServiceUrl(),并在getServiceUrl()方法中将IP和端口号拼接成 IP:PORT 的形式

private String getServiceUrl(String serviceName){
    ServiceInstance serviceInstance = discoveryClient.getInstances(serviceName).get(0);
    return serviceInstance.getHost() + ":" + serviceInstance.getPort();
}

具体的实现方式就是调用DiscoveryClient对象的getInstances()方法,并传入服务的名称,从Nacos注册中心中获取一个ServiceInstance类型的List集合,从List集合中获取第1个元素,也就是从List集合中获取到一个ServiceInstance对象,从ServiceInstance对象中获取到IP地址和端口号,并将其拼接成 IP:PORT 的形式。

定义服务提供者名称

在 shop-order 的 OrderServiceImpl 类定义两个成员变量 userServerproductServer,表示用户微服务和商品微服务的服务名称,并将其分别复制为 server-userserver-product

private String userServer = "server-user";
private String productServer = "server-product";

userServer 的值需要与用户微服务下的 application.yml 文件中的如下配置的值相同。

修改提交订单逻辑

在 shop-order 的 OrderServiceImpl 类的 saveOrder()方法中,将硬编码的用户微服务和商品微服务的 IP 和端口修改成从 Nacos 注册中心中获取,涉及改动的代码。

  • 添加获取用户微服务与商品微服务的 IP 和端口号的代码片段,如下所示。
//从Nacos服务中获取用户服务与商品服务的地址
String userUrl = this.getServiceUrl(userServer);
String productUrl = this.getServiceUrl(productServer);
  • 修改使用 restTemplate 获取用户信息的代码片段。
User user = restTemplate.getForObject("http://" + userUrl + "/user/get/" + orderParams.getUserId(), User.class);
if (user == null){
    throw new RuntimeException("未获取到用户信息: " + JSONObject.toJSONString(orderParams));
}
  • 修改使用 restTemplate 获取商品信息的代码片段
Product product = restTemplate.getForObject("http://" + productUrl + "/product/get/" + orderParams.getProductId(), Product.class);
if (product == null){
    throw new RuntimeException("未获取到商品信息: " + JSONObject.toJSONString(orderParams));
}
  • 修改使用 restTemplate 扣减商品库存的代码片段
Result<Integer> result = restTemplate.getForObject("http://" + productUrl + "/product/update_count/" + orderParams.getProductId() + "/" + orderParams.getCount(), Result.class);
if (result.getCode() != HttpCode.SUCCESS){
    throw new RuntimeException("库存扣减失败");
}

用户微服务和商品微服务在服务器上部署多份的话,之前的程序无法实现服务调用的负载均衡功能。所以需要为服务引入负载均衡功能。

posted @ 2024-11-06 22:54  Jacob-Chen  阅读(40)  评论(0)    收藏  举报