• 微服务环境搭建


    目录

    案例准备

    技术选型

    模块设计

    微服务调用

    创建一个父工程 

     版本对应:

     创建基础模块

    创建实体类

    创建用户微服务

    对pom文件进行更改

    微服务模块设计

    创建商品微服务

     创建订单微服务

    测试微服务

     用户微服务controller层

    商品微服务controller层

     启动微服务

     在网页上测试

    订单微服务调用其他微服务 

     订单微服务controller层

    运行结果


    我们本次是使用的电商项目中的商品、订单、用户为案例进行讲解。

    案例准备

    技术选型

    maven:3.5.4

    数据库:MySQL 5.7

    持久层: SpingData Jpa/Mybatis-plus

    其他: SpringCloud Alibaba 技术栈

    模块设计

    springcloud-shop父工程

    shop-common 公共模块【实体类】

    shop-user 用户微服务 【端口: 807x】

    shop-product 商品微服务 【端口: 808x】

    shop-order 订单微服务 【端口: 809x】

    微服务调用

    在微服务架构中,最常见的场景就是微服务之间的相互调用。我们以电商系统中常见的用户下单为 例来演示微服务的调用:客户向订单微服务发起一个下单的请求,在进行保存订单之前需要调用商品微 服务查询商品的信息。 我们一般把服务的主动调用方称为服务消费者,把服务的被调用方称为服务提供者。 在这种场景下,订单微服务就是一个服务消费者, 商品微服务就是一个服务提供者。

    创建一个父工程 

     

    新工程需要更改Maven仓库地址

    由于这里不需要写代码,我们将src删除

    pom.xml文件中添加下面内容,锁定版本依赖

    1. <properties>
    2. <java.version>1.8java.version>
    3. <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    4. <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
    5. <spring-boot.version>2.3.2.RELEASEspring-boot.version>
    6. <spring-cloud.version>Hoxton.SR9spring-cloud.version>
    7. <spring-cloud-alibaba.version>2.2.6.RELEASEspring-cloud-alibaba.version>
    8. properties>
    9. <dependencyManagement>
    10. <dependencies>
    11. <dependency>
    12. <groupId>org.springframework.bootgroupId>
    13. <artifactId>spring-boot-dependenciesartifactId>
    14. <version>${spring-boot.version}version>
    15. <type>pomtype>
    16. <scope>importscope>
    17. dependency>
    18. dependencies>
    19. dependencyManagement>

     我们所创建的模块会继承版本,由于微服务架构是由单个单个的SpringBoot项目组合而成的,所有需要锁定版本依赖,如果版本不一致的话,在之后的项目开发中写同样的代码会出现各种各样的问题

     版本对应:

    https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
     

     创建基础模块

    再建一个Maven,作为我们的一个公共模块

     Maven项目比SpringBoot项目的优点在于,它可以选择继承父模块 

    导入基础模块的依赖

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.bootgroupId>
    4. <artifactId>spring-boot-starter-data-jpaartifactId>
    5. dependency>
    6. <dependency>
    7. <groupId>org.projectlombokgroupId>
    8. <artifactId>lombokartifactId>
    9. dependency>
    10. <dependency>
    11. <groupId>com.alibabagroupId>
    12. <artifactId>fastjsonartifactId>
    13. <version>1.2.56version>
    14. dependency>
    15. <dependency>
    16. <groupId>mysqlgroupId>
    17. <artifactId>mysql-connector-javaartifactId>
    18. <version>5.1.44version>
    19. dependency>
    20. dependencies>

     可以看见,我们刚刚创建的模块自动添加了父模块

    对应的父模块也自动添加了子模块 

    如果创建的是Maven项目的话,继承父模块是可以直接加好的,但SpringBoot项目则需要直接手动添加

    创建实体类

    我们在common项目中添加点代码,我们的公共模块主要就是添加一些实体类,工具包等等。

    用户实体类

    1. package com.oyang.model;
    2. import lombok.Data;
    3. //用户
    4. @Data//不再去写set和get方法
    5. @NoArgsConstructor
    6. @AllArgsConstructor
    7. public class User {
    8. private Integer uid;//主键
    9. private String username;//用户名
    10. private String password;//密码
    11. private String telephone;//手机号
    12. }

     商品实体类

    1. package com.oyang.model;
    2. import lombok.Data;
    3. //商品
    4. @Data
    5. @NoArgsConstructor
    6. @AllArgsConstructor
    7. public class Product {
    8. private Integer pid;//主键
    9. private String pname;//商品名称
    10. private Double pprice;//商品价格
    11. private Integer stock;//库存
    12. }

    订单实体

    1. package com.oyang.model;
    2. import lombok.Data;
    3. //订单
    4. @Data
    5. @NoArgsConstructor
    6. @AllArgsConstructor
    7. public class Order {
    8. private Long oid;//订单id
    9. //用户
    10. private Integer uid;//用户id
    11. private String username;//用户名
    12. //商品
    13. private Integer pid;//商品id
    14. private String pname;//商品名称
    15. private Double pprice;//商品单价
    16. //数量
    17. private Integer number;//购买数量
    18. }

    由于我们要做微服务。比如用户微服务,商品微服务,订单微服务而微服务所对应的肯定有对应的实体类

    创建用户微服务

    步骤:

    1 创建模块 导入依赖

    2 创建SpringBoot主类

    3 加入配置文件

    4 创建必要的接口和实现类(controller service dao)

    新建一个SpringBoot模块命名为shop-user ,然后进行下面操作

     不用去勾选,这里版本不对应

     这里是没有继承父模块的,所以我们需要自己添加。

    对pom文件进行更改

    只剩下两行,再添加继承父模块的代码,我们直接去common工程拷贝就行 下面的依赖也需要做出改变

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.bootgroupId>
    4. <artifactId>spring-boot-starter-webartifactId>
    5. dependency>
    6. <dependency>
    7. <groupId>com.oyanggroupId>
    8. <artifactId>shop-commonartifactId>
    9. <version>1.0-SNAPSHOTversion>
    10. dependency>
    11. dependencies>

     由此可见,在基础模块里面,我们可以定义一些共用的pom依赖,比如:数据库连接、解析JSON对象、Lombok组件

    由于微服务要同时启动,所以我们需要更改端口名

    微服务模块设计

    上面有提到

    1. springcloud-shop父工程
    2. shop-common 公共模块【实体类】
    3. shop-user 用户微服务 【端口: 807x】
    4. shop-product 商品微服务 【端口: 808x】
    5. shop-order 订单微服务 【端口: 809x】

     修改yml文件

    创建商品微服务

    ---与用户微服务一样的操作,这里就不意义演示了

    更改pom

    添加下面依赖

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.bootgroupId>
    4. <artifactId>spring-boot-starter-webartifactId>
    5. dependency>
    6. <dependency>
    7. <groupId>com.oyanggroupId>
    8. <artifactId>shop-commonartifactId>
    9. <version>1.0-SNAPSHOTversion>
    10. dependency>
    11. dependencies>

     更改yml文件

     创建订单微服务

    ---与用户微服务一样的操作,这里就不意义演示了

    更改pom

    添加依赖

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.springframework.bootgroupId>
    4. <artifactId>spring-boot-starter-webartifactId>
    5. dependency>
    6. <dependency>
    7. <groupId>com.oyanggroupId>
    8. <artifactId>shop-commonartifactId>
    9. <version>1.0-SNAPSHOTversion>
    10. dependency>
    11. dependencies>

     更改yml文件

    测试微服务

    我们模拟场景:订单微服务调用商品的微服务以及用户的微服务(跨项目调用功能) 

     用户微服务controller层

    1. package com.oyang.shopuser.controller;
    2. import com.oyang.model.User;
    3. import org.springframework.web.bind.annotation.PathVariable;
    4. import org.springframework.web.bind.annotation.RequestMapping;
    5. import org.springframework.web.bind.annotation.RestController;
    6. /**
    7. * @author oyang
    8. * @site https://blog.csdn.net
    9. * @qq 1828190940
    10. * @create 2022-11-24 16:07
    11. */
    12. @RestController
    13. @RequestMapping("/user")
    14. public class UserController {
    15. //获取单个用户
    16. @RequestMapping("/get/{id}")
    17. public User get(@PathVariable("id") Integer id){
    18. return new User(id,"oyang","123","15580XXXXXX");
    19. }
    20. }

    商品微服务controller层

    1. package com.oyang.shopproduct.controller;
    2. import com.oyang.model.Product;
    3. import org.springframework.web.bind.annotation.PathVariable;
    4. import org.springframework.web.bind.annotation.RequestMapping;
    5. import org.springframework.web.bind.annotation.RestController;
    6. /**
    7. * @author oyang
    8. * @site https://blog.csdn.net
    9. * @qq 1828190940
    10. * @create 2022-11-24 16:07
    11. */
    12. @RestController
    13. @RequestMapping("/product")
    14. public class ProductController {
    15. //返回商品信息
    16. @RequestMapping("/get/{pid}")
    17. public Product get(@PathVariable("pid") Integer pid){
    18. return new Product(pid,"凡人修仙传",30d,30);
    19. }
    20. }

     启动微服务

    我们先测试一下能否启动项目

    这里test中Junit报了错,我们直接把它删掉,因为用不到 再次启动可以看见,我们的用户微服务已经启动成功了 

    将商品微服务启动

     在网页上测试

     用户微服务

    商品微服务 

    订单微服务调用其他微服务 

    微服务之间采用Restful等轻量级http协议相互调用

    在启动类中添加

    1. @Bean
    2. public RestTemplate restTemplate(){
    3. return new RestTemplate();
    4. }

     可这个需要在配置类中才有效,为什么可以加载启动类呢?

    原因是启动类中@SpringBootApplication注解包含了配置类,代表当前启动类就可以当做一个配置类来使用

     订单微服务controller层

    1. package com.oyang.shoporder.controller;
    2. import com.oyang.model.Order;
    3. import com.oyang.model.Product;
    4. import com.oyang.model.User;
    5. import org.springframework.beans.factory.annotation.Autowired;
    6. import org.springframework.web.bind.annotation.PathVariable;
    7. import org.springframework.web.bind.annotation.RequestMapping;
    8. import org.springframework.web.bind.annotation.RestController;
    9. import org.springframework.web.client.RestTemplate;
    10. /**
    11. * @author oyang
    12. * @site https://blog.csdn.net
    13. * @qq 1828190940
    14. * @create 2022-11-24 16:07
    15. */
    16. @RestController
    17. @RequestMapping("/order")
    18. public class OrderController {
    19. @Autowired
    20. private RestTemplate restTemplate;
    21. @RequestMapping("/get/{uid}/{pid}")
    22. public Order get(@PathVariable("uid") Integer uid,@PathVariable("pid") Integer pid){
    23. /**
    24. * 要在订单微服务中调用 用户微服务、商品微服务--也就意味着跨项目调用
    25. * httpClients
    26. */
    27. //得到用户对象
    28. User user = restTemplate.getForObject("http://localhost:8070/user/get/" + uid, User.class);
    29. //得到商品对象
    30. Product product = restTemplate.getForObject("http://localhost:8080/product/get/" + pid, Product.class);
    31. Order order = new Order();
    32. order.setUsername(user.getUsername());
    33. order.setUid(user.getUid());
    34. order.setPprice(product.getPprice());
    35. order.setPname(product.getPname());
    36. order.setPid(product.getPid());
    37. order.setOid(System.currentTimeMillis());//随机生成id
    38. order.setNumber(product.getStock());
    39. return order;
    40. }
    41. }

    运行结果

     

  • 相关阅读:
    一道简单题引发的思考
    leetcode 47. 全排列 II(java)
    SpringMVC(一)
    浅谈齿轮行业MES解决方案的模块和功能
    Unity中的协程
    mxnet gluon GRU 文档
    BSV上的高效 zk-SNARK:技术解释
    Zookeeper的api使用
    Bootstrap,浅入一下。
    分组查询以及筛选的区别
  • 原文地址:https://blog.csdn.net/weixin_65211978/article/details/128083577