目录
一、微服务架构
一、SpringCould简介
三、SpringCould技术栈
四、关于Cloud各种组件的停更/升级/替换
五、微服务架构编码构建
创建微服务cloud整体聚合父工程Project步骤:
父工程pom
1.Rest微服务工程构建
微服务提供者支付module模块cloud-provider-payment8001
1. 新建module
2.改pom
3. 写yml
4. 主启动类
5. 业务类
6.测试
2.热部署Devtools
3. 微服务消费者订单module模块cloud-consumer-order80
4. 工程重构
融合组装一切 让分布式变得更加简单
分布式服务架构包含:
springcloud官方文档(Hoxton SR5):https://cloud.spring.io/spring-cloud-static/Hoxton.SR5/reference/htmlsingle/
springcloud中文文档:https://www.springcloud.cc/
springcloud中国社区文档:http://docs.springcloud.cn/
https://www.bookstack.cn/read/spring-cloud-docs/docs-index.md
京东商品微服务架构
阿里云微服务架构
京东物流微服务架构
微服务之间的调度
主流核心技术
springboot git源码地址:https://github.com/spring-projects/spring-boot/releases/
springboot2.5新特性:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.5-Release-Notes
springboot最新版
springcould版本
springboot和springcould之间的版本依赖关系
https://spring.io/projects/spring-cloud#overview
官方对应关系:http://start.spring.io/actuator/info (使用json工具查看)
SpringCloud文档:https://cloud.spring.io/spring-cloud-static/Hoxton.SR1/reference/htmlsingle/
SpringCloud 中文文档:https://www.bookstack.cn/read/spring-cloud-docs/docs-index.md
SpringBoot文档:https://docs.spring.io/spring-boot/docs/2.3.12.RELEASE/reference/htmlsingle/
约定>配置>编码
1.New Project
2.聚合总父工程名字
3.maven不要用自带的版本 用3.5以上的
4.设置字符编码
5.注解生效激活
6.java编译版本选8
7.File Type过滤
(对pom文件里面的架包内容进行优化) 删掉src文件夹
在pom.xml文件中加上
pom
然后把
下的内容都用下面这些替换了。
UTF-8
1.8
1.8
4.12
1.18.10
1.2.17
8.0.18
1.1.20
1.3.2
org.springframework.boot
spring-boot-dependencies
2.3.12.RELEASE
pom
import
org.springframework.cloud
spring-cloud-dependencies
Hoxton.SR12
pom
import
com.alibaba.cloud
spring-cloud-alibaba-dependencies
2.1.2.RELEASE
pom
import
mysql
mysql-connector-java
${mysql.version}
runtime
com.alibaba
druid-spring-boot-starter
${druid.version}
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis.spring.boot.version}
junit
junit
${junit.version}
log4j
log4j
${log4j.version}
org.springframework.boot
spring-boot-maven-plugin
true
true
maven中dependencyManagement标签:
子项目中,如果不指定,默认和父项目dependencyManagement标签中的版本一致,并且父项目dependencyManagement标签只是规定了版本号,具体引入依赖还是子项目引入。
maven中跳过单元测试
父工程创建完成后执行mvn:install
将父工程发布到仓库方便子工程继承
后期发布项目时可以先install,如果出现success表示maven跟idea的整合是没问题的
如果要发布其他的可以先clean 后 install
微服务模块构建步骤:
子项目名:cloud-provider-payment8001
调整父pom文件 cloud2021永远在最上面 payment8001是子项目
在子项目名:cloud-provider-payment8001的pom中添加依赖
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.mybatis.spring.boot
mybatis-spring-boot-starter
com.alibaba
druid-spring-boot-starter
1.1.20
mysql
mysql-connector-java
8.0.11
org.springframework.boot
spring-boot-starter-jdbc
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
在resources目录下新建application.yml配置文件
#微服务建议一定要写服务端口号和微服务名称
server:
#端口号
port: 8001
spring:
application:
#微服务名称
name: cloud-payment-service
#数据库配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#mysql5.x的没有cj
driver-class-name: com.mysql.jdbc.Driver
#记得先创建数据库
url: jdbc:mysql://localhost:3306/db2021?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
#mybatis配置
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.aurora.springcloud.entities #所有Entity别名类所在包
在java包下创建主启动类com.aurora.springcloud.PaymentMain8001
@SpringBootApplication
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class,args);
}
}
建表SQL
CREATE DATABASE db2021;
USE db2021;
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;
INSERT INTO payment(`serial`)VALUES("aaabb01");
建entities
在springcloud包下新建实体类entities.Payment
//这三个注解是lombok的,除了导入依赖,idea还需要安装插件(具体操作问度娘)
@Data //set/get方法
@AllArgsConstructor //有参构造器
@NoArgsConstructor //无参构造器
public class Payment implements Serializable {
private Long id;
private String serial;
}
在entities包下新建CommonResult(json封装体,传给前端的)
//返回给前端的通用json数据串
@Data //set/get方法
@AllArgsConstructor //有参构造器
@NoArgsConstructor //无参构造器
public class CommonResult {
//最常见的错误 404 not_found 所以一般java的通用返回结果集是数字编码和异常信息
//所以定义code 和 message 能够给前端一个良好的显示
private Integer code;
private String message;
private T data; //泛型,对应类型的json数据
//自定义两个参数的构造方法
public CommonResult(Integer code, String message){
this(code, message, null);
}
}
3.dao
在springcloud包下新建dao.PaymentDao接口
@Mapper //ibatis下的注解
public interface PaymentDao { //Dao 跟数据库打交道
public int create(Payment payment); //写操作
public Payment getPaymentById(@Param("id") Long id); //读操作
// 加上@Param注解,mapper中就可以采用#{}的方式把@Param注解括号内的参数进行引用
//这里用读和写进行演示,有兴趣的可以自己加其他的方法
}
4.mapper
在resources目录下新建mapper目录,然后新建PaymentMapper.xml
insert into payment(serial) values (#{serial});
application.yml中跟mybatis整合了,mapper的位置如下,所以要新建mapper及xml
5.service
在springcloud包下新建service.PaymentService接口
public interface PaymentService {
int create(Payment payment);
Payment getPaymentById(@Param("id") Long id);
}
在service包下新建impl.PaymentServiceIpml实现类
@Service
public class PaymentServiceIpml implements PaymentService {
@Resource //@Autowired也可以
private PaymentDao paymentDao;
public int create(Payment payment){
return paymentDao.create(payment);
}
public Payment getPaymentById(Long id){
return paymentDao.getPaymentById(id);
}
}
6.controller
在springcloud包下新建controller.PaymentController
@RestController
@Slf4j //日志
public class PaymentController {
@Resource
private PaymentService paymentService;
//前后端分离,所以不能直接返回对象,数据要先经过CommonResult封装再返回
@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, "插入数据库成功", 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, "查询成功", payment);
}else{
return new CommonResult(444, "没有对应记录,查询ID:" + id);
}
}
}
启动项目
浏览器中输入:http://localhost:8001/payment/get/31 返回json串
浏览器输入:http://localhost:8001/payment/create?serial=aurora 进行写入操作报错,浏览器一般不支持直接发送post请求,所以需要使用工具进行测试。(这里用的是Postman)
Postman下载地址:https://www.postman.com/downloads/
重新测试查询 没问题 输入create插入
可看到数据插入成功,查看数据库中也有刚刚插入的数据
(只能在开发阶段使用的插件,自动热部署,简言之更改代码后能自动重启生效)
1.在cloud-provider-payment8001项目的pom中添加热部署依赖(已经添加了)
org.springframework.boot
spring-boot-devtools
runtime
true
2.添加一个插件到父类总工程的pom.xml里 (之前也加好了的)
org.springframework.boot
spring-boot-maven-plugin
true
true
3.开启自动编译的选项
4.热注册开启
按住组合键Ctrl+Shift+Alt+/
,选中Registry…
勾上下图的勾
5.重启IDEA
开完之后感觉有点卡,虽然能自动部署,但是代码提示变慢了,等电脑好一点再开
把第四步打上的勾去掉(原本打上的就不用去掉了),然后重启idea就可以了。
1. 新建Module
工程名:cloud-consumer-order80
2. 改pom
往pom中添加:
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
3. 写yml
在resources目录下新建application.yml文件
#访问一个网站时,默认是80端口,给用户80端口,用户就可以不用加端口直接访问页面
server:
port: 80
4. 主启动
com.aurora.springcloud.OrderMain80
@SpringBootApplication
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class,args);
}
}
5. 写业务
1.复制cloud-provider-payment8001项目里的entities(里面2个实体类)到本项目(cloud-consumer-order80)的springcloud包下。
(因为是客户端消费者调用订单服务 所以只需要有controller就行)
2.在springcloud包下新建controller.orderController
@RestController
@Slf4j
public class OrderController {
public static final String PAYMENT_URL = "http://localhost:8001"; //地址先写死 后面再进行更改
@Resource
private RestTemplate restTemplate;
//因为是客户端 所以要发GetMapping的请求
@GetMapping("/consumer/payment/create") //consumer代表客户 用来区分是客户端 p
public CommonResult create(Payment payment){
log.info("********插入的数据:" + payment);
//写操作需要用post postForObject分别有三个参数:请求地址,请求参数,返回的对象类型
return restTemplate.postForObject(PAYMENT_URL + "/payment/create", payment, CommonResult.class);
}
@GetMapping("/consumer/payment/get/{id}")
public CommonResult getPayment(@PathVariable("id") Long id){
log.info("********查询的id:" + id);
//getForObject两个参数:请求地址,返回的对象类型
return restTemplate.getForObject(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);
}
}
要实现两个服务之间的调用 要使用restTemplate,相当于对httpClient进行了封装 实现了订单微服务和支付微服务之间的横向调用
RestTemplate提供了多种便捷访问远程Http服务的方法,
是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集官网地址
https://docs.spring.io/spring-framework/docs/5.2.9.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html
使用
使用restTemplate访问restful接口非常的简单粗暴无脑。
(url, requestMap, ResponseBean.class)这三个参数分别代表
REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
3.配置restTemplate 在springcloud包下新建config.ApplicationContextConfig
@Configuration
public class ApplicationContextConfig {
//往容器中添加一个RestTemplate
//RestTemplate提供了多种便捷访问远程http访问的方法
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
//Bean相当于用注解的方式依赖注入 appationContext.xml
6. 测试
启动两个项目进行测试,两个都启动后,右下角会弹出个Run Dashboard的提示,点击Show... 就会把运行的项目合并在一起显示:
在postman中输入http://localhost/consumer/payment/get/31
成功查询到数据。(消费者不需要知道端口的概念 所以不需要加端口号)
然后输入 http://localhost/consumer/payment/create?serial=emily 插入一条数据
插入成功
两个工程中有重复部分,进行重构。
1. 新建新工程:cloud-api-commons
2. 改pom
添加依赖:
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
cn.hutool
hutool-all
5.1.0
3.entities
拷贝entities到本项目中
4.maven命令clean install (将entities的maven打包发布上传到公用的本地库里面,供其他另外两个库调用)
5.订单80和支付8001分别改造
a.删除各自的原先有过的entities文件夹(停止项目运行再做这个操作)
删除后两个项目报错 需要引用刚刚maven中install后的架包(pom中的‘g’ ‘a’ ‘v’坐标)
b.给两个项目引入打包后项目的坐标
com.aurora.springcloud
cloud-api-commons
${project.version}
引入后就可以发现两个项目报错的红色都消失了
查询 :http://localhost/consumer/payment/get/13
插入:http://localhost/consumer/payment/create?serial=komorebi
目前项目关系图
下一篇:SpringCloud(H版&Alibaba)技术(二) —— Eureka服务注册与发现