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 ...
随机推荐
- numpy模块的基本使用
numpy(Numerical Python)提供了python对多维数组对象的支持:ndarray,具有矢量运算能力,快速.节省空间.numpy支持高级大量的维度数组与矩阵运算,此外也针对数组运算提 ...
- 判断变量是否不为空,函数isset()、!empty()与!is_null()的比较
转载:https://blog.csdn.net/qq_38812954/article/details/79581785 判断变量的值,尤其是判断他们是否不为空,我们有以下4种方法: if(isse ...
- 表单中submit和button按钮的区别!
对于表单的按钮以前知道submit和button有区别,但没有深入探索,今天刚好又碰到这个问题,看了下网络上这位朋友已经有现成的总结了,而且比较到位,拿来跟大家分享下(原文地址:http://blog ...
- 洛谷P1346 电车【最短路】
题目:https://www.luogu.org/problemnew/show/P1346 题意:n个路口,每个路口有好几条轨道,默认指向给出的第一个路口. 如果要换到另外的轨道去需要按一次开关.问 ...
- jenkins安装和国内镜像配置
直接替换 $JENKINS_HOME/updates/default.json 成腾讯云的地址即可: JENKINS_HOME=xxxxxxxxx sed -i 's/http:\/\/updates ...
- [Angular 8] Lazy loading with dynamic loading syntax
@NgModule({ declarations: [AppComponent, HomeComponent], imports: [ BrowserModule, MatSidenavModule, ...
- svn优点跟缺点?
优点: 1.svn优点:集中式管理,管理方式在服务端配置好,客户端只需要同步提交即可,使用方便,操作简单,很容易就可以上手 2.在服务端统一控制好访问权限,利用代码的安全管理. 3.所有的代码以服务端 ...
- BST(二叉查找树)
https://songlee24.github.io/2015/01/13/binary-search-tree/ 二叉查找树(BST) 发表于 2015-01-13 | 分类于 Basic ...
- 数据结构实验之图论七:驴友计划【迪杰斯特拉算法】(SDUT 3363)
分析:可以求简单的任意两点间最短距离的稍微变形,一个板子题. #include <iostream> #include <bits/stdc++.h> using names ...
- Java实现多线程生产者消费者模式的两种方法
生产者消费者模式:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据.生产者生产一个,消费者消费一个,不断循环. 第一种实现方法,用BlockingQueue阻塞队 ...