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 ...
随机推荐
- MySQL之JDBC插入、修改、删除封装集于一个方法
1. 先建四个包 ① com.tz.entity 实体包 ② com.tz.dao 数据访问层包 -> com.tz.dao.impl 实现包 ③ com.tz.util 工具类包 ④ com. ...
- win10 注册DLL
昨天用c++写了一个ocx插件,注册就死活注册不上,折腾了半天1.打开C:\Windows\SysWOW64 文件夹 找到cmd 右键管理员运行 2.将你的插件或者dll放到此目录下3.regsvr ...
- MVC框架和MTV框架
MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View)和控制器(Controller),具有耦合性低 ...
- vscode源码编译疑难问题
最近把原来老的源码merge到了新的1.15版本源码,以前的依赖问题会导致各种错误,Loading "gc-signals" failed啦,Error: %1 is not a ...
- django rest framework框架中都有那些组件
1.权限 2.认证 3.访问频率 4.序列化 5.路由 6.视图 7.分页 8.解析器 9.渲染器 规定页面显示的效果(无用) https://www.cnblogs.com/Rivend/p/118 ...
- 找到一些经验,关于使用thymeleaf时遇到的一些问题
最近一直在使用spring boot,所以自然而然的使用了thymeleaf,但是我想说习惯了jsp之后使用thymeleaf真实觉得不顺手,在使用thymeleaf中也遇到了一些问题,在这里记录一下 ...
- vue:概要
一.环境 #安装nodejs-官网安装包配置环境变量 node -v #安装webpack npm install webpack -g #安装vue-cli npm install vue-cli ...
- java调出cmd窗口长ping某个ip
package lct.conference.test; import java.io.IOException; public class Test { public static void main ...
- 007_Python3 字符串
字符串是 Python 中最常用的数据类型.我们可以使用引号( ' 或 " )来创建字符串. 创建字符串很简单,只要为变量分配一个值即可. 例如: var1 = 'Hello World!' ...
- Lua 常用函数 一
lua_getallocf lua_Alloc lua_getallocf (lua_State *L, void **ud); 返回给定状态机的内存分配器函数.如果 ud 不是 NULL ,Lua ...