微服务环境搭建及简单实例
1、案例准备
我这次是使用的电商项目中的商品、订单为案例进行讲解演示。 望大家能够更加容易理解。
2、模块设计
- spring_cloud 父工程
- shop-common 公共模块【实体类】 《实体类,公共依赖,工具类。》
- shop-product 商品微服务 【端口: 8080~8089】
- shop-order 订单微服务 【端口: 8090~8099】
2.1、微服务调用
在微服务架构中,最常见的场景就是微服务之间的相互调用。我们以电商系统中常见的用户下单为
例来演示微服务的调用:客户向订单微服务发起一个下单的请求,在进行保存订单之前需要调用商品微服务查询商品的信息。
我们一般把服务的主动调用方称为服务消费者,把服务的被调用方称为服务提供者。
在这种场景下,订单微服务就是一个服务消费者, 商品微服务就是一个服务提供者。
3、项目实例
3.1、创建父工程
①:打开IDEA,创建Maven工程,创建名字为spring_clound
的父工程
②:在pom.xml添加依赖
<!--引入父依赖-->
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.3.2.RELEASE</version>
</parent>
<!--定义版本号-->
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!--springcloud的版本号-->
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
<!--springcloud alibaba的版本-->
<spring-cloud-alibaba.version>2.2.5.RELEASE</spring-cloud-alibaba.version>
</properties>
<!--dependencyManagement:负责jar的管理,不负责jar的下载-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
版本对应如下:
3.2、创建基础模块(微服务)
点击项目名(父工程名)->new
->Moudle
创建以下子模块。
shop-common
公共的实体类
shop-order
订单微服务
shop-product
商品微服务
3.2.1、shop-common
公共的实体类
①:在pom.xml文件添加如下依赖:
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
</dependencies>
②:创建实体类(Order类、Product类)
@Data
@TableName("shop_order")
public class Order {
@TableId(type = IdType.AUTO)
private Integer oid;
private Integer uid;
private String username;
private Integer pid;
private String pname;
private Double pprice;
private Integer number;
}
@Data
@TableName("shop_product")
public class Product {
@TableId(type = IdType.AUTO)
private Integer pid;
private String pname;
private Double pprice;
private Integer stock;
}
3.2.2、shop-product
商品微服务
①:在pom.xml文件中添加依赖(MySql依赖要加在子模块中)
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--独立部署的工程-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
②:创建工程主类
@SpringBootApplication
@MapperScan(basePackages = {"com.fyx.mapper"})
public class ProductApplictaion {
public static void main(String[] args) {
SpringApplication.run(ProductApplictaion.class,args);
}
}
③:创建配置文件application.properties
#给服务器设置端口号
server.port=8081
#微服务的名称
spring.application.name=shop-product
#数据源信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db_movie?serverTimezone=Asia/Shanghai&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123@qwe
mybatis-plus.mapper-locations=classpath:mapper/*.xml
#日志信息
logging.level.com.fyx.mapper=debug
④:创建ProductDao接口
public interface ProductMapper extends BaseMapper<Product> {
}
⑤:创建ProductService接口
@Service
public class ProductService {
@Resource
private ProductMapper productMapper;
/**
* 通过商品id查询商品信息详情
* @param pid
* @return
*/
public Product findById(Integer pid){
return productMapper.selectById(pid);
}
}
⑥:创建ProductController类
@RestController
@RequestMapping("product")
public class productController {
@Autowired
private ProductService productService;
/**
* 根据商品id查询商品信息
* @param pid
* @return
*/
@GetMapping("findById")
public Product findById(@RequestParam Integer pid){
return productService.findById(pid);
}
}
⑦:启动工程,通过地址访问(我这里使用了nginx)
3.2.3、shop-order
订单微服务
①:添加springboot依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
②:创建启动类
@SpringBootApplication
@MapperScan(basePackages = {"com.fyx.mapper"})
@EnableFeignClients//开启fegin注解
public class OrderAppliction {
public static void main(String[] args) {
SpringApplication.run(OrderAppliction.class,args);
}
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
③:创建配置文件application.properties
server.port=8091
#微服务的名称
spring.application.name=shop-order
#数据源信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db_movie?serverTimezone=Asia/Shanghai&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123@qwe
mybatis-plus.mapper-locations=classpath:mapper/*.xml
#日志信息
logging.level.com.fyx.mapper=debug
④:创建OrderDao接口
public interface OrderMapper extends BaseMapper<Order> {
}
⑤:创建OrderService接口
@Service
public class OrderService {
@Resource
private OrderMapper orderMapper;
/**
* 保存订单
* @param order
* @return
*/
public boolean saveOrder(Order order){
return orderMapper.insert(order)>0;
}
/**
* 根据id修改数量
* @param order
* @return
*/
public int insertAll(@RequestBody Order order){
order.setNumber(order.getNumber()+2);
order.setOid(order.getOid());
System.out.println("/******"+order.getNumber());
return orderMapper.updateById(order);
}
}
⑥:创建OrderController类
@RestController
@RequestMapping("order")
public class OrderController {
@Resource
private OrderService orderService;
@Resource
private ProductFegin productFegin;
@GetMapping("payOrder")
public String payOrder(Integer pid,Integer num){//商品id,商品数量
Order order = new Order();
//获取信息
order.setUid(2);
order.setUsername("付亚星");
order.setNumber(num);
order.setPid(pid);
//设置商品的名称和价格 必须调用商品微服务? 如何调用远程的微服务。 (1)基于Http协议 RestFul调用 适合微服务 (2)基于Tcp协议 RPC 适合dubbo
//springboot为你封装了一个基于http协议的远程调用的工具类。
Product product = productFegin.findById(pid);
//远程微服务的地址。 Class:表示调用远程接口后返回的数据类型 args:远程接口需要的参数.
//思考: 硬编码:如果商品微服务的地址发生改变 那么 订单微服务代码也要改变。
if(product!=null && order.getUsername().equals("付亚星")) {
order.setNumber(order.getNumber());
order.setPname(product.getPname());
order.setPprice(product.getPprice());
orderService.saveOrder(order);
System.out.println(order);
}else {
throw new RuntimeException("商品已下架");
}
return "下单成功!";
}
⑦:启动工程并在浏览器上测试