SpringCloud(三)了解了概念,现在来验证一下,玩个小案例
案例说明
按照普通方式模拟一个微服务之间的调用,后续将一步步使用Spring Cloud的组件对案例进行改造。
需求:

完整业务流程图:

案例数据库环境准备
CREATE TABLE products(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(50), #商品名称
price DOUBLE,
flag VARCHAR(2), #上架状态
goods_desc VARCHAR(100), #商品描述
images VARCHAR(400), #商品图片
goods_stock INT, #商品库存
goods_type VARCHAR(20) #商品类型
);
基于SpringBoot来构造工程环境,工程模块关系如下所示:

父工程 szx-parent
<!--父工程打包方式-->
<packaging>pom</packaging>
<!--spring boot 父启动器依赖-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<dependencies>
<!--web依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--日志依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--lombok工具-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
<!-- Actuator可以帮助你监控和管理Spring Boot应用-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<!--编译插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
<!--打包插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
公共组件微服务
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>szx-parent</artifactId>
<groupId>com.szx</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>szx-service-common</artifactId>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<!--pojo持久化使用-->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>javax.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "products")
public class Products implements Serializable {
@Id
@Column(name = "id")
private int id;
private String name;
private double price;
private String flag;
private String goodsDesc;
private String images;
private long goodsStock;
private String goodsType;
}
商品微服务
商品微服务是服务提供者,页面静态化微服务是服务的消费者
在商品微服务的pom文件中,引入公共组件坐标
<dependencies>
<dependency>
<groupId>com.szx</groupId>
<artifactId>szx-service-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
在 application.properties 文件中配置端口、应用名、数据库连接等信息
#配置端口号,在微服务的集群环境中,通常会为每一个微服务叠加
server.port=9000
#微服务中的唯一标识
spring.application.name=szx-service-product
#MySQL数据库连接配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdata?serverTimezone=UTC&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123
Mapper接口开发
/**
* @Program: springclouddemo
* @Author: XiaoXing
* @Create: 2021-02-03 21:23
* @Description: Product连接数据接口
* 现在使用Mybatis-plus组件,该组件是Mybatis的加强版
* 能给与SpringBoot进行非常友好的整合
* 对比Mybatis框架只有使用便捷的改变
* 没有具体功能的改变
* 具体使用:只需要让Mapper接口继承BaseMapper即可
**/
public interface ProductMapper extends BaseMapper<Products> {
}
serive层开发
public interface ProductService {
/**
* 通过商品Id查询商品接口
* @param id
* @return
*/
public Products selectProductById(Integer id);
}
@Service("productService")
public class ProductServiceImpl implements ProductService {
@Autowired
private ProductMapper productMapper;
@Override
public Products selectProductById(Integer id) {
return productMapper.selectById(id);
}
}
controller层开发
@RestController
@RequestMapping("/product")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/selectProductById/{id}")
public Products selectProductById(@PathVariable Integer id){
return productService.selectProductById(id);
}
}
启动类
@SpringBootApplication
@MapperScan("com.szx.mapper")
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class,args);
}
}
页面静态化微服务
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>szx-parent</artifactId>
<groupId>com.szx</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>szx-service-page</artifactId>
<dependencies>
<dependency>
<groupId>com.szx</groupId>
<artifactId>szx-service-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
#配置端口号,在微服务的集群环境中,通常会为每一个微服务叠加
server.port=9100
#微服务中的唯一标识
spring.application.name=szx-service-page
#MySQL数据库连接配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdata?serverTimezone=UTC&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123
#开启驼峰命名
mybatis-plus.configuration.map-underscore-to-camel-case=true
@SpringBootApplication
public class PageApplication {
public static void main(String[] args) {
SpringApplication.run(PageApplication.class,args);
}
/**
* 向容器中注入一个RestTemplate,封装了HttpClient
* @return
*/
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
@RestController
@RequestMapping("/page")
public class PageController {
private static final String PRODUCTURL = "http://localhost:9000/product/selectProductById/";
@Autowired
private RestTemplate restTemplate;
@GetMapping("/getProduct/{id}")
public Products getProduct(@PathVariable Integer id){
//发送http请求给商品微服务,将id传递过去,获取id所对应的Product对象
Products products = restTemplate.getForObject(PRODUCTURL + id, Products.class);
return products;
}
}
案例代码问题分析
我们在页面静态化微服务中使用RestTemplate调用商品微服务的商品状态接口时(Restful API 接口)。在微服务分布式集群环境下会存在什么问题呢?怎么解决?
存在的问题:
1)在服务消费者中,我们把url地址硬编码到代码中,不方便后期维护。
2)服务提供者只有一个服务,即便服务提供者形成集群,服务消费者还需要自己实现负载均衡。
3)在服务消费者中,不清楚服务提供者的状态。
4)服务消费者调用服务提供者时候,如果出现故障能否及时发现不向用户抛出异常页面?
5)RestTemplate这种请求调用方式是否还有优化空间?能不能类似于Dubbo那样玩?
6)这么多的微服务统一认证如何实现?
7)配置文件每次都修改好多个很麻烦!?
8)…
上述分析出的问题,其实就是微服务架构中必然面临的一些问题:
1)服务管理:自动注册与发现、状态监管
2)服务负载均衡
3)熔断
4)远程过程调用
5)网关拦截、路由转发
6)统一认证
7)集中式配置管理,配置信息实时自动更新
这些问题,Spring Cloud 体系都有解决方案
453

被折叠的 条评论
为什么被折叠?



