一、微服务架构
业界大牛马丁.福勒(Martin Fowler) 这样描述微服务:论文网址:链接
微服务架构是一种架构模式,它提倡将单一应⽤程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相协作(通常是基于HTTP协议的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。
SpringCloud :
分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体,俗称微服务全家桶
SpringCloud中包含了20+种技术。
1、技术选型
查看SpringCloud 和SpringBoo版本兼容性
查看SpringCloud 对其余各个技术版本的兼容性 需要转换成JSON进行查看
2、学习版本定稿
学习时必须和定稿版本一致
技术 | 版本 |
---|---|
Spring Cloud | Hoxton.SR1 |
Spring Boot | 2.2.2.RELEASE |
Spring Cloud Alibaba | 2.1.0.RELEASE |
Java | 8 |
Maven | 3.5 |
MySQL | 5.7 |
3、Cloud各种组件的停更/升级/替换
停更不停用
- bug不管了
- 不接受GitHub合并请求
- 不再发布新版本
服务注册中心:
Eureka
停更Zookeeper
可用Consul
可用但不推荐Nacos
完美替换Eureka 推荐
服务调用:
Ribbon
可用LoadBalancer
Spring 新推出 打算替代Ribbon
服务调用2:
Fiegn
停更OpenFiegn
可用 推荐
服务降低熔断:
Hystrix
停更但企业大部分在使用resilience4j
官网推荐,国外使用的居多Sentinel
阿里巴巴的 强烈推荐
服务网关:
Zuul
停更Zuul2
胎死腹中gateway
Spring家的,推荐
服务配置:
config
不推荐apolo
携程的 推荐Nacos
阿里巴巴的 推荐
服务总线:
Bus
不推荐Nacos
推荐
二、SpringCloud工程创建
此父工程声明了 SpringCloud 和SpringBoot的版本 Pom工程
1、实用maven生成一个空的 project 即可 【project】
1.1 pom
```xml <?xml version=”1.0” encoding=”UTF-8”?>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
<a name="be9a9cdc"></a>
##
<a name="fXrki"></a>
## 2、支付模块构建
> 约定>配置>编码
<a name="ogFrv"></a>
### 2.1 改module
创建一个module,cloud-provider-payment8001<br />因为是在父工程下创建的,所以自动继承了父工程,<br />同时 父工程中也多出来这个:
```xml
<modules>
<module>cloud-provider-payment8001</module>
</modules>
2.2 改pom
<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-actuator</artifactId>
</dependency>
<!-- mybatis 和SpringBoot 整合-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- druid 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2.3 写yaml
#微服务建议一定要写服务端口号和微服务名称
server:
#端口号
port: 8001
spring:
application:
#微服务名称
name: cloud-payment-service
#数据库配置
datasource:
type: com.zaxxer.hikari.HikariDataSource
#mysql5.x的没有cj
driver-class-name: com.mysql.cj.jdbc.Driver
#记得先创建数据库
url: jdbc:mysql://localhost:3306/springCloud?characterEncoding=utf-8&useSSL=false&serverTimezone=Hongkong&allowPublicKeyRetrieval=true
username: root
password: 123456
#mybatis配置
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.springcloud.entities #所有Entity别名类所在包
2.4 主启动类
@SpringBootApplication
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class,args);
}
}
2.5 业务类
CREATE TABLE `payment`(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`serial` VARCHAR(200) DEFAULT'',
PRIMARY KEY(`id`)
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
entities
支付表实体类
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Payment implements Serializable {
private Long id;
private String serial;
}
通用 结果集实体类
@NoArgsConstructor
@AllArgsConstructor
@Data
public class CommonResult<T> {
private Integer code;
private String message;
private T data;
public CommonResult(Integer code, String message) {
this.code = code;
this.message = message;
}
}
dao
@Mapper
public interface PaymentDao {
int create(Payment payment);
Payment getPaymentById(@Param("id") Long id);
}
mapper
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.springcloud.dao.PaymentDao">
<resultMap id="BaseResultMap" type="com.springcloud.entities.Payment">
<id column="id" property="id" jdbcType="BIGINT"/>
<id column="serial" property="serial" jdbcType="VARCHAR"/>
</resultMap>
<!-- Payment标红了不用管,因为我们已经在yml文件中指定了Payment的位置了 -->
<insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id">
insert into payment(serial) values(#{serial});
</insert>
<!--返回用resultMap,防止命名不规范-->
<select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap">
select * from payment where id=#{id};
</select>
</mapper>
service
@Service
public class PaymentServiceImpl implements PaymentService {
@Autowired
private PaymentDao paymentDao;
@Override
public int create(Payment payment) {
return paymentDao.create(payment);
}
@Override
public Payment getPaymentById(Long id) {
return paymentDao.getPaymentById(id);
}
}
controller
@Slf4j
@RestController
public class PaymentController {
@Autowired
private PaymentService paymentService;
@PostMapping("/payment/create")
public CommonResult create(@RequestBody Payment payment) {
int result = paymentService.create(payment);
log.info("******插入的数据为:" + payment);
log.info("******插入结果:" + result);
if (result > 0) {
// 插入成功
return new CommonResult(200, "插入数据库成功!" + serverPort, result);
} else {
return new CommonResult(444, "插入数据库失败!");
}
}
@GetMapping("/payment/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") Long id) {
Payment payment = paymentService.getPaymentById(id);
log.info("******查询结果:" + payment);
if (payment != null) {
// 查询成功
return new CommonResult(200, "查询成功!" + serverPort, payment);
} else {
return new CommonResult(444, "没有对应记录, 查询Id: " + id);
}
}
}
三、Devtools 热部署
添加devtools 依赖和pom插件
<!-- devtools 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- devtools 插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
Ctrl+Alt+Shift+/ —->registry——>打勾
重启IDEA ——- 热部署OK!
四、消费者工程
1、使用RestTemplate来进行远程调用
- RedisTemplate 提供了多种便捷的访问远程HTTP服务的方法
- 是一种简单轻便的访问restful服务模板类,是Spring提供的用户访问Rest服务的客户端模板工具集。
2、使用RestTemplate
(url ,requestMap,ResponseBean.class)
这三个参数分别代表了(Rest请求地址、请求参数、Http响应转换被转换成的对象类型)
3、将RestTemplate添加到容器中
@Configuration
public class WebConfig {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
4、使用RestTemplate 调用8001端口
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@PostMapping("/consumer/payment/create")
public CommonResult<Payment> create(Payment payment) {
log.info("********插入的数据: " + payment);
//postForObject分别有三个参数:请求地址,请求参数,返回的对象类型
return restTemplate.postForObject(PAYMENT_URL + "/payment/create", payment, CommonResult.class);
}
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable("id") Long id) {
log.info("********插入的数据: " + id);
//getForObject两个参数:请求地址,返回的对象类型
return restTemplate.getForObject(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);
}
}
五、实体类工程
为了更简洁的代码,减少冗余
<dependencies>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
maven执行命令 clean
install
把其余工程中的实体类删除即可,然后把80 和8001的pom中加入commons工程依赖