Spring Cloud(7.2):配置Producer Server
我们首先创建一个生产者服务。这里以一个商品价格服务为例,这个微服务可以对商品-价格信息进行增删改查,当有商品-价格信息被更新或删除,则该微服务发送消息,告诉其他调用它的系统这条信息已经被修改。
配置pom.xml
首先,在pom.xml中添加spring-cloud-stream和spring-cloud-starter-stream-kafka两个依赖
<!-- Spring cloud: stream -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<!-- Spring cloud starter: kafka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
此外,它还是一个Eureka Client和Config Client,如何配置Eureka Client和Config Client请看前面章节。
配置发射器(source),通道(channel),绑定器(binder)及Application
public interface ProductPriceSource {
@Output("productPriceOutput")
MessageChannel productPriceOutput();
}
[注] 这里创建了一个叫“productPriceOutput”的自定义发射通道,如果不使用自定义,可以直接使用org.springframework.cloud.stream.messaging.Source接口及叫output的发射通道(下面的yml文件会讲如何配置)。
@Component
public class ProductPriceMessageSender { @Autowired
private ProductPriceSource source; private static final Logger logger = LoggerFactory.getLogger(ProductPriceMessageSender.class); /**
* The product is expired and need to send kafka message to consumer service to remove it from cache(redis).
*
* @param productId
*/
public void sendMessage(Long productId) {
logger.info(String.format(">>>>> Sending Kafka message: [productId = %s].", productId.toString()));
source.productPriceOutput().send(MessageBuilder.withPayload(productId).build());
}
}
[注] 这里配置了一个发射器bean,当有商品-价格信息被更新或删除,则调用该bean,把消息发布到消息队列。
@SpringBootApplication
@EnableBinding({ ProductPriceSource.class })
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
[注] Application中加入@EnableBinding注解,并把定义好的发射通道(output)或接收通道(input)绑定到该服务中。可以绑定多个。
配置application.yml
## Spring info
spring:
# Stream/Kafka info
cloud:
stream:
bindings:
# output -> productPriceOutput (自定义通道)
productPriceOutput:
# 要写入消息的消息队列的名称
destination: productPriceTopic
# 发送和接收消息类型
content-type: application/json
# 使用kafka作为消息总线
kafka:
binder:
# 运行着kafka服务器的网络地址
brokers: www.mytools.com
API及其他业务逻辑
@Controller
@RequestMapping("pp")
public class ProductPriceController { @Autowired
private ProductPriceService productPriceService; @GetMapping(value = "find/all")
@ResponseBody
public List<ProductPriceEntity> findAll() {
return productPriceService.findAll();
} @GetMapping(value = "find/productId/{productId}")
@ResponseBody
public ProductPriceEntity find(@PathVariable String productId) {
return productPriceService.findById(Long.valueOf(productId));
} @GetMapping(value = "add/productId/{productId}/product/{product}/price/{price}")
@ResponseBody
public String save(@PathVariable String productId, @PathVariable String product, @PathVariable String price) {
return productPriceService.save(Long.valueOf(productId), product, new BigDecimal(price));
} @GetMapping(value = "update/productId/{productId}/product/{product}/price/{price}")
@ResponseBody
public String update(@PathVariable String productId, @PathVariable String product, @PathVariable String price) {
return productPriceService.update(Long.valueOf(productId), product, new BigDecimal(price));
} @GetMapping(value = "delete/productId/{productId}")
@ResponseBody
public String delete(@PathVariable String productId) {
return productPriceService.delete(Long.valueOf(productId));
}
}
[注] 这里创建了几个常规的,包括增删改查的API。
@Service
public class ProductPriceService { private static final Map<Long, ProductPriceEntity> db = new ConcurrentHashMap<>(); static {
ProductPriceEntity row1 = new ProductPriceEntity(1L, "Apple", new BigDecimal("8.5"));
ProductPriceEntity row2 = new ProductPriceEntity(2L, "Watermelon", new BigDecimal("2.2"));
ProductPriceEntity row3 = new ProductPriceEntity(3L, "Grape", new BigDecimal("6.8"));
db.put(1L, row1);
db.put(2L, row2);
db.put(3L, row3);
} @Autowired
private ProductPriceMessageSender sender; public List<ProductPriceEntity> findAll() { List<ProductPriceEntity> results = new ArrayList<>();
results.addAll(db.values()); return results;
} public ProductPriceEntity findById(Long productId) {
return db.get(productId);
} public String save(Long productId, String product, BigDecimal price) {
if (db.containsKey(productId)) {
return String.format("[WARN] Product which productId = %s already exists in DB.", productId.toString());
} else {
ProductPriceEntity param = new ProductPriceEntity(productId, product, price);
db.put(productId, param);
return String.format("Save %s completed.", param);
}
} public String update(Long productId, String product, BigDecimal price) {
if (db.containsKey(productId)) {
ProductPriceEntity param = new ProductPriceEntity(productId, product, price);
db.put(productId, param);
// [UPDATE] send to kafka
sender.sendMessage(productId);
return String.format("Update %s completed.", param);
} else {
return String.format("[WARN] No product which productId = %s in DB.", productId.toString());
}
} public String delete(Long productId) {
if (db.containsKey(productId)) {
ProductPriceEntity result = db.remove(productId);
// [DELETE] send to kafka
sender.sendMessage(productId);
return String.format("Delete %s completed.", result.toString());
} else {
return String.format("[WARN] No product which productId = %s in DB.", productId.toString());
}
}
}
[注] 这里使用一个Map来模拟DB。并且当有商品-价格信息被更新或删除时,才调用ProductPriceMessageSender发送消息。ProductPriceEntity的代码如下:
public class ProductPriceEntity implements Serializable {
private static final long serialVersionUID = 1L;
private Long productId;
private String product;
private BigDecimal price;
public ProductPriceEntity() {
}
public ProductPriceEntity(Long productId, String product, BigDecimal price) {
super();
this.productId = productId;
this.product = product;
this.price = price;
}
public Long getProductId() {
return productId;
}
public void setProductId(Long productId) {
this.productId = productId;
}
public String getProduct() {
return product;
}
public void setProduct(String product) {
this.product = product;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
@Override
public String toString() {
return "ProductPriceEntity [productId=" + productId + ", product=" + product + ", price=" + price + "]";
}
}
ProductPriceEntity
Spring Cloud(7.2):配置Producer Server的更多相关文章
- Spring Cloud Config(配置中心)
每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 一.简介 Spring Cloud Config为分布式系统中的外部配置提供服务器和客 ...
- spring cloud config将配置存储在数据库中
Spring Cloud Config Server最常见是将配置文件放在本地或者远程Git仓库,放在本地是将将所有的配置文件统一写在Config Server工程目录下,如果需要修改配置,需要重启c ...
- 跟我学SpringCloud | 第六篇:Spring Cloud Config Github配置中心
SpringCloud系列教程 | 第六篇:Spring Cloud Config Github配置中心 Springboot: 2.1.6.RELEASE SpringCloud: Greenwic ...
- Spring Cloud Config 实现配置中心,看这一篇就够了
Spring Cloud Config 是 Spring Cloud 家族中最早的配置中心,虽然后来又发布了 Consul 可以代替配置中心功能,但是 Config 依然适用于 Spring Clou ...
- spring cloud 2.x版本 Eureka Server服务注册中心教程
本文采用Spring cloud本文为2.1.8RELEASE,version=Greenwich.SR3 1.创建服务注册中心 1.1 新建Spring boot工程:eureka-server 1 ...
- Spring Cloud Config的配置中心获取不到最新配置信息的问题
Spring Cloud Config的配置中心获取不到最新配置信息的问题 http://blog.didispace.com/spring-cloud-tips-config-tmp-clear/
- Spring Cloud Feign 自定义配置(重试、拦截与错误码处理) 实践
Spring Cloud Feign 自定义配置(重试.拦截与错误码处理) 实践 目录 Spring Cloud Feign 自定义配置(重试.拦截与错误码处理) 实践 引子 FeignClient的 ...
- 笔记:Spring Cloud Ribbon 客户端配置详解
自动化配置 由于 Ribbon 中定义的每一个接口都有多种不同的策略实现,同时这些接口之间又有一定的依赖关系,Spring Cloud Ribbon 中的自动化配置能够很方便的自动化构建接口的具体实现 ...
- Spring Cloud Config 分布式配置中心使用教程
一.简介 在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件.在Spring Cloud中,有分布式配置中心组件spring cloud config ...
随机推荐
- Linux下安装nginx实现伪分布
1.安装 Nginx 的编译环境 gcc yum install gcc-c++ 2.nginx 的 http 模块使用 pcre 解析正则表达式,所以安装 perl 兼容的正则表达式库 yum in ...
- socket、端口、进程的关系
本文属网络编程部分.socket的引入是为了解决不同计算机间进程间通信的问题. 端口是TCP/IP协议中的概念,描述的是TCP协议上的对应的应用,可以理解为基于TCP的系统服务,或者说系统进程!如下图 ...
- Python3 报错'latin-1' codec can't encode character 解决方案
Python3 报错'latin-1' codec can't encode character 解决方案 在更新数据库操作时,报错: UnicodeEncodeError: 'latin-1' co ...
- 002_simulink中显示模块中的名字
(一)Display--->Hide Automatic Names(√去掉)
- 学到了林海峰,武沛齐讲的Day17完-6 文件操作
参考 https://www.cnblogs.com/linhaifeng/articles/5984922.html f=open('陈粒1',encoding='utf-8') ope ...
- HttpURLConnection getInputStream 400异常的解决
判断getResponseCode,当返回不是HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_CREATED, HttpURLConnection. ...
- 1825:【01NOIP提高组】数的划分
#include<bits/stdc++.h> using namespace std; ],tot; void dfs(int num,int pos) { if(pos==k) ]) ...
- ROS launch 总结
ROS launch 总结 转自博客:https://www.cnblogs.com/Jessica-jie/p/6961837.html 1 运行Launch文件2 新建Launch文件3 在na ...
- 已安装gcc编译器,但./configure还是提示找不到编译器(分析)
1.编译nginx前, ./configure检查提示找不到C编译器 [root@test nginx-]# ./configure checking for OS + Linux -.el7.x86 ...
- 调整 全局jvm 大小 tomcat 调整jvm大小
z最近公司换了一个线上的windows服务器,原来的内存48g,现在2g.项目启动报内存不足.又重新安装jre 安装jre 教程链接:(谢谢各位博友) https://www.genban.org/t ...