书接上文
创建商品模块和库存模块
- 使用maven创建一个库存服务模块,这样父工程下就有service-order和service-store两个子模块
- 将订单模块中的依赖复制到库存模块中
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
- 在resource下创建bootstrap.yml
server:
port: 8100
spring:
application:
name: service-store
cloud:
nacos:
server-addr: localhost:8848
discovery:
ephemeral: false
- 创建主启动类
@EnableDiscoveryClient
@SpringBootApplication
public class StoreApplication {
public static void main(String[] args) {
SpringApplication.run(StoreApplication.class,args);
}
}
再重复上面4步创建一个service-goods的子模块
现在就有3个模块了,service-goods商品模块,service-store库存模块,service-order订单模块。
测试
库存模块
记得启动nocas服务
- 在库存模块中创建StoreController类
@RestController
@RequestMapping("/store")
class StoreController{
@Value("${server.port}")
String port;
@GetMapping("/{skuID}")
public Map<String, Object> getStoreNum(@PathVariable String skuID){
Map<String, Object> map = new HashMap<>();
map.put("port",port);
map.put("storeNum",100L);
return map;
}
}
- 启动程序,在浏览器中输入地址localhost:8101/store/1
浏览器中就会显示我们存入map的数据,库存数量为100
商品模块
- 创建商品实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GoodsSkuDTO {
private Long id;
private Long storeNum;
private String skuNo;
private String name;
private String size;
private BigDecimal price;
}
- 创建RestTemplateConfig配置类通过RestTemplate来进行http连接请求
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
- 创建GoodsController类进行测试
@RestController
@RequestMapping("/goods")
class GoodsController{
@Autowired
private RestTemplate restTemplate;
@GetMapping("/{skuID}")
public GoodsSkuDTO getStoreNum(@PathVariable String skuID) throws JsonProcessingException {
GoodsSkuDTO goodsSkuDTO = new GoodsSkuDTO();
goodsSkuDTO.setId(1L);
goodsSkuDTO.setSkuNo("101");
goodsSkuDTO.setName("天暗星手办");
goodsSkuDTO.setSize("Xl");
goodsSkuDTO.setPrice(BigDecimal.valueOf(300.00));
//从库存服务拿到库存量
String res = restTemplate.getForObject("http://localhost:8101/store/" + skuID, String.class);
ObjectMapper objectMapper = new ObjectMapper();
Map map = objectMapper.readValue(res, Map.class);//将json字符串转为map对象
Long storeNum = Long.valueOf(map.get("storeNum").toString());
System.out.println("当前库存端口服务端口:"+map.get("port"));
goodsSkuDTO.setStoreNum(storeNum);
return goodsSkuDTO;
}
}
- 运行程序(库存模块也要启动起来),在浏览器输入地址localhost:8200/goods/1
浏览器中就会显示出数据,有商品本身的属性,还有库存模块中的库存数量。
负载均衡
当然这样我们只能请求到固定端口的地址"http://localhost:8101/store/" + skuID
所以需要使用负载均衡来将请求分配到其他端口的服务上
实现资源的合理利用,平衡服务器的负载
- 在商品模块的pom中引入所需的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
-
在RestTemplateConfig配置类中的restTemplate方法上加上@LoadBalanced注解
-
在GoodsController类中将http请求地址
String res = restTemplate.getForObject("http://localhost:8101/store/" + skuID, String.class);
修改为
String res = restTemplate.getForObject("http://service-store/store/" + skuID, String.class);
启动两个不同端口的库存服务和一个商品服务,在商品页面发送多个请求
@LoadBalanced注解默认的负载均衡方式是轮询,请求会轮流交给第一台服务到最后一台服务处理。