https://spring.io/projects/spring-cloud-stream
https://github.com/sa-spring/stream-loan
调研
开发
添加orderService,配置好事件驱动
source/发送者用的是supplier,连续的发送事件,但是我的期望设计是由特定事件驱动,需要用到streamBridge.参考
处理者也可以返回消息,需要使用consumer参考
测试
先测试事件驱动架构,在自动化生成请求的情况下;
测试pos-order和pos-delivery在有网页访问的情况下
测试由pos-cart驱动pos-order
Tech Solution
伪代码+配置文件
pos-order
配置文件
copy pos-cart
spring.io 生成一个micro service文件
作为微服务的配置/discovery配置/gateaway配置/
cloudstream 配置 ???
直接去掉?
1
2
3
4
5
6
7
8
9
10
11spring:
cloud:
function:
definition: placeOrder
stream:
function:
bindings:
deliver-order: String
bindings:
loan:
destination: output补充api
- openApi中在responses使用基本类型的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/order/place
post:
sumary: place an order
operationId: placeOrder
tags:
- order
requestBody:
description: order info
content:
application/json:
schema:
type: string
required: true
responses:
'200':
description: Expected
content:
application/json:
schema:
type: boolean
default:
description: Unexpected
content:
application/json:
schema:
$ref: "#/components/schemas/Error"//Info format: productA|productB|addr:CityA
rest
- restController implements OrdersApi
- override method 调用service中方法
1
2
3
4
5
6public ResponseEntity<boolean> placeOrder( String orderInfo){
boolean res = orderService.placeOrder(orderInfo);
if(!res)
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
return new ResponseEntity<>(res,HttpStatus.OK);
}service
OrderService
- placeOrder
OrderServiceImpl
- EDA-Impl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
OrderServiceImp implements OrderService{
StreamBridge streamBridge
boolean placeOrder(String orderInfo){
//calculate number of products
for(str : info){
if(str.startsWith("addr:")){
addr = new StringBuilder(str.substring(4)).toString();
}
else
cnt++;
}
String deliveryInfo = String.format("%d|%s",cnt,addr);
return streamBridge.send("deliver-order",deliveryInfo);
}
}
//单向
postman跑不动:用curl来测试
1 | curl -H "Content-Type:application/json" -X POST -d '{"orderInfo":"3|CityA}"' http://localhost:8085/api/order/place |
pos-delivery
配置:类似loan-checker √
- application.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15spring:
cloud:
function:
definition: #Consume方法名
stream:
function:
bindings:
checkOrder-in-0: receive
#consumer方法名-in-0: 发送方send的首个参数
bindings:
#发送的消息名称 保持一致
order-declined:
destination: order-declined
order-approved:
destination: order-approvedDeliveryApplication √
1
2
3
4
5main{}
public Consumer<String> deliverCart(){
return new CartDelivery();
}CartDelivery √
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18CartDelivery implements Consumer<String>{
public static final Logger log = LoggerFactory.getLogger(CartDelivery.class);
private StreamBridge streamBridge;
public void accept(String info){
//number to calculate fee
String[] infos = info.split("\\|");
int cnt = Integer.parseInt(infos[0]);
double fee = 1.25*cnt;
String msg = String.format("deliver %d product(s) to %s,fee is %f",cnt,infos[1],fee);
log.info(msg+"\n");
streamBridge.send("delivery",message(msg));
}
private static final <T> Message<T> message(T val) {
return MessageBuilder.withPayload(val).build();
}
}进阶版:添加DeliveryInfo 记录重量和地区信息
cart中添加用rest发送消息的controller方法 参考
在CartServiceImp:checkout方法中添加生成信息
todo:在vmware上做
discovery&&gateway能正常运转
其他微服务controller问题
cart中添加调用
一些插曲——遇到的问题和解决措施
因为内存不足在另一台虚拟机上重配了环境,配置maven的时候需要移除旧的未成功安装的Java环J境并重新配置Java环境
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64/
/usr/local/src/java/jdk-18.0.1
1 | mvn install:install-file -Dfile=/home/avril/SA-2022/HW07/stream-loan/loan-model/target/loan-model-0.0.1.jar -DgroupId=com.example -DartifactId=loan-model -Dversion=0.0.1 -Dpackaging=jar |
rest-controller无法调用:
- api之后不需要写getMapping
- 扫描包