如何处理微服务之间的通信和数据一致性?


✨✨祝屏幕前的兄弟姐妹们每天都有好运相伴左右,一定要天天开心哦!✨✨ 
🎈🎈作者主页: 喔的嘛呀🎈🎈

目录

引言

一、微服务通信

1、同步通信:HTTP

1.1.同步通信示例代码:

1.2. 发送HTTP POST请求并获取响应:

2、异步通信

使用消息队列实现异步通信的示例代码:

二、数据一致性

1. 分布式事务

2. 数据同步

3. 幂等性

三、示例

步骤一:创建商品服务和用户服务

商品服务(Product Service)代码示例:

用户服务(User Service)代码示例:

步骤二:引入Spring Cloud分布式事务支持

步骤三:创建订单服务(Order Service)

订单服务(Order Service)代码示例:

注意事项:

总结

目录

引言

一、微服务通信​​​​​​​

1、同步通信:HTTP

1.1.同步通信示例代码:

1.2. 发送HTTP POST请求并获取响应:

2、异步通信

使用消息队列实现异步通信的示例代码:

二、数据一致性

1. 分布式事务

2. 数据同步

3. 幂等性

三、示例

步骤一:创建商品服务和用户服务

商品服务(Product Service)代码示例:

用户服务(User Service)代码示例:

步骤二:引入Spring Cloud分布式事务支持

步骤三:创建订单服务(Order Service)

订单服务(Order Service)代码示例:

注意事项:

总结



引言

在微服务架构中,处理微服务之间的通信和数据一致性是非常重要的。通信需要高效可靠,数据一致性要求保证在分布式环境下的可靠性和正确性。下面我们将详细介绍如何处理微服务之间的通信和数据一致性。

一、微服务通信

在微服务架构中,微服务之间的通信可以采用不同的方式,包括同步和异步通信。常用的通信方式包括HTTP和消息队列等。下面将详细介绍这些通信方式,并提供相应的代码示例。

1、同步通信:HTTP

同步通信是指请求方发送请求后,一直等待直到接收到响应。这种通信方式简单直接,但容易导致调用方和被调用方之间的耦合度高,服务雪崩风险大。

在微服务架构中,同步通信是指客户端发送请求后等待服务端响应的通信方式。常用的同步通信方式包括使用HTTP协议。下面将详细介绍如何使用Java的HttpURLConnection实现同步通信,并附上代码示例。

1.1.同步通信示例代码:

 发送HTTP GET请求并获取响应:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;public class SyncHttpClient {public static void main(String[] args) {try {// 创建URL对象URL url = new URL("http://localhost:8080/api/example");// 创建HttpURLConnection对象HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 设置请求方法为GETconn.setRequestMethod("GET");// 设置连接超时时间为5秒conn.setConnectTimeout(5000);// 设置读取超时时间为5秒conn.setReadTimeout(5000);// 发起请求并获取响应码int responseCode = conn.getResponseCode();System.out.println("Response Code: " + responseCode);// 读取响应内容BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));String inputLine;StringBuilder response = new StringBuilder();while ((inputLine = in.readLine()) != null) {response.append(inputLine);}in.close();// 打印响应内容System.out.println("Response Content: " + response.toString());} catch (Exception e) {e.printStackTrace();}}
}

在上述代码中,我们使用HttpURLConnection对象创建了一个GET请求,并设置了连接超时时间和读取超时时间。然后我们发起了请求,并获取了响应码和响应内容,最后打印出来。

1.2. 发送HTTP POST请求并获取响应:

import java.io.DataOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;public class SyncHttpClient {public static void main(String[] args) {try {// 创建URL对象URL url = new URL("http://localhost:8080/api/example");// 创建HttpURLConnection对象HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 设置请求方法为POSTconn.setRequestMethod("POST");// 设置连接超时时间为5秒conn.setConnectTimeout(5000);// 设置读取超时时间为5秒conn.setReadTimeout(5000);// 允许输入输出流conn.setDoOutput(true);// 发送POST请求DataOutputStream out = new DataOutputStream(conn.getOutputStream());out.writeBytes("key1=value1&key2=value2");out.flush();out.close();// 获取响应码int responseCode = conn.getResponseCode();System.out.println("Response Code: " + responseCode);} catch (Exception e) {e.printStackTrace();}}
}

以上就是关于使用Java的HttpURLConnection实现同步通信的示例代码。这些代码可以帮助你理解如何在Java中进行同步通信,并根据需要发送GET或POST请求并获取响应。

2、异步通信

异步通信是指客户端发送请求后不需要等待响应,而是继续执行后续操作,待服务端处理完请求后发送响应。在微服务架构中,常用的异步通信方式包括使用消息队列。

使用消息队列实现异步通信的示例代码:

// 消息生产者发送消息的代码
@Component
public class MessageProducer {@Autowiredprivate RabbitTemplate rabbitTemplate;public void sendMessage(String message) {rabbitTemplate.convertAndSend("my-exchange", "my-routing-key", message);}
}// 消息消费者处理消息的代码
@Component
public class MessageConsumer {@RabbitListener(queues = "my-queue")public void handleMessage(String message) {System.out.println("Received message: " + message);}
}

以上是关于微服务通信的示例代码,其中包括了同步通信(HTTP)和异步通信(消息队列)。这些通信方式可以根据具体场景选择使用,以实现不同的功能需求。

二、数据一致性

在分布式系统中,确保数据一致性是至关重要的。下面详细介绍分布式系统中数据一致性的相关问题和解决方案。

1. 分布式事务

分布式事务是指涉及多个数据库或服务的事务操作。在分布式环境中,保证事务的原子性、一致性、隔离性和持久性是具有挑战性的。常用的分布式事务解决方案包括:

  • 2PC(Two-Phase Commit):两阶段提交协议,通过协调器协调所有参与者,确保所有参与者要么全部提交,要么全部回滚。但是2PC存在单点故障和阻塞的问题。
  • TCC(Try-Confirm-Cancel):Try阶段尝试执行操作,Confirm阶段确认执行操作,Cancel阶段取消执行操作。TCC通过业务逻辑实现分布式事务,适用于高并发场景。
  • Saga模式:一种长事务的模式,通过将一个大事务拆分为多个小事务,并通过补偿操作实现事务的最终一致性。

2. 数据同步

数据同步是保持不同数据副本之间数据一致性的过程。常见的数据同步方式包括:

  • 主从复制:主数据库向从数据库定期发送更新数据的操作,从而保持数据一致性。
  • 发布-订阅模式:通过消息队列实现数据的发布和订阅,实现数据的异步传输和处理。

3. 幂等性

幂等性是指对同一操作的多次执行具有相同的效果。在分布式系统中,保证接口的幂等性是确保数据一致性的重要手段。常见的幂等性实现方式包括:

  • 接口设计幂等性:通过接口设计保证同一请求的多次执行不会产生重复的效果。
  • 唯一请求标识:每个请求都携带唯一标识,服务端通过标识判断请求的幂等性。

综上所述,分布式系统中数据一致性是一个复杂而重要的问题,需要综合考虑业务需求和系统架构,选择合适的解决方案来保证数据的一致性。

在分布式系统中,数据一致性是确保不同节点上的数据在时间上保持一致的重要性。在处理分布式系统中的数据一致性时,有几个关键概念和技术需要考虑:

  1. CAP定理:CAP定理指出,一个分布式系统不可能同时满足一致性(Consistency)、可用性(Availability)和分区容忍性(Partition Tolerance)这三个特性,只能满足其中两个。在实际系统设计中需要根据实际需求权衡这三个特性。

  2. ACID和BASE:ACID是传统数据库事务的特性,包括原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。而BASE是基本可用(Basically Available)、软状态(Soft state)和最终一致性(Eventual Consistency)的缩写,是NoSQL数据库的设计理念。

  3. 一致性模型:在分布式系统中,常用的一致性模型包括强一致性、弱一致性和最终一致性。强一致性要求数据写入后立即对所有节点可见,而最终一致性允许在一段时间内出现不一致的情况,但最终会达到一致状态。

  4. 分布式事务:分布式事务是指涉及多个参与者的事务操作。常用的分布式事务解决方案包括基于消息队列的最终一致性方案、TCC(Try-Confirm-Cancel)等。

  5. 数据同步:数据同步是保持分布式系统中数据副本之间一致性的过程。常用的数据同步方式包括主从复制和发布-订阅模式。

  6. 幂等性:幂等性是指对同一操作的多次执行具有相同效果。在分布式系统中,保证接口的幂等性是确保数据一致性的重要手段。

综上所述,数据一致性在分布式系统中是一个复杂而重要的问题,需要根据具体的业务需求和系统架构选择合适的一致性模型和技术方案。

三、示例

电商系统中,确保下单成功时同时扣减商品库存和用户余额是一个常见的场景,可以使用分布式事务来保证数据一致性。下面是一个简单的示例,使用Spring Boot和Spring Cloud的分布式事务管理来实现这一功能。

步骤一:创建商品服务和用户服务

首先,我们需要创建两个微服务,一个是商品服务,负责管理商品库存;另一个是用户服务,负责管理用户余额。这里使用Spring Boot创建两个简单的RESTful服务。

商品服务(Product Service)代码示例:
@RestController
public class ProductController {private int productStock = 100; // 初始商品库存为100@PostMapping("/product/decreaseStock")public boolean decreaseStock(@RequestParam int quantity) {if (productStock >= quantity) {productStock -= quantity;return true;} else {return false;}}@GetMapping("/product/stock")public int getStock() {return productStock;}
}
用户服务(User Service)代码示例:
@RestController
public class UserController {private int userBalance = 1000; // 初始用户余额为1000@PostMapping("/user/decreaseBalance")public boolean decreaseBalance(@RequestParam int amount) {if (userBalance >= amount) {userBalance -= amount;return true;} else {return false;}}@GetMapping("/user/balance")public int getBalance() {return userBalance;}
}

步骤二:引入Spring Cloud分布式事务支持

在每个服务的pom.xml文件中添加Spring Cloud的依赖:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

并在各自的配置文件中配置Seata分布式事务的相关信息。

步骤三:创建订单服务(Order Service)

订单服务负责处理下单逻辑,并在下单成功时调用商品服务和用户服务接口来扣减库存和余额。

订单服务(Order Service)代码示例:
@RestController
public class OrderController {@Autowiredprivate RestTemplate restTemplate;@PostMapping("/order")public boolean createOrder(@RequestParam int productId, @RequestParam int quantity, @RequestParam int userId, @RequestParam int amount) {// 调用商品服务扣减库存boolean decreaseStockResult = restTemplate.postForObject("http://product-service/product/decreaseStock?quantity=" + quantity, null, Boolean.class);if (!decreaseStockResult) {throw new RuntimeException("Decrease stock failed");}// 调用用户服务扣减余额boolean decreaseBalanceResult = restTemplate.postForObject("http://user-service/user/decreaseBalance?amount=" + amount, null, Boolean.class);if (!decreaseBalanceResult) {// 如果扣减余额失败,需要回滚商品服务扣减的库存restTemplate.postForObject("http://product-service/product/increaseStock?quantity=" + quantity, null, Boolean.class);throw new RuntimeException("Decrease balance failed");}// 创建订单成功return true;}
}

在订单服务中,我们使用RestTemplate来调用商品服务和用户服务的接口。如果任何一个扣减操作失败,就会抛出异常并回滚之前的操作,保证数据的一致性。

注意事项:

  1. 在实际项目中,应考虑分布式事务的性能和并发情况,合理设计事务的范围和边界。
  2. 应注意分布式事务可能存在的问题,如分布式事务协调器单点故障、性能瓶颈等。
  3. 可以考虑使用分布式事务中间件如Seata、TCC框架等来简化分布式事务管理。

总结

通过使用消息队列实现微服务之间的异步通信,以及使用分布式事务保证数据的一致性,我们可以有效地处理微服务架构中的通信和数据一致性问题。这样的架构具有高可靠性、可扩展性和灵活性,适用于大型复杂系统

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/721750.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1、Ajax、get、post、ajax,随机颜色

一、Ajax初始 1、什么是Ajax&#xff1f; 异步的JavaScript和xml 2、xml是什么&#xff1f; 一种标记语言&#xff0c;传输和存储数据----------现在用JSON传输数据 3、Ajax的作用 局部加载 可以使网页异步更新 4、Ajax的原理或者步骤(6步) 创建Ajax对象 if (window.X…

2024年租用阿里云服务器多少钱?阿里云服务器租用价格表(最新版)

2024年租用阿里云服务器一年多少钱&#xff1f;不同时期阿里云服务器的租用价格不同&#xff0c;随着2024年阿里云上云采购季活动的开启和阿里云最新一轮的云产品降价调整&#xff0c;阿里云服务器租用价格也做了一些调整&#xff0c;配置最低的1核1G云服务器收费标准为22.8/月…

NAT模式 LVS负载均衡部署

一 架构图 二 文字表述过程 1 当客户端 发起请求报文是: 源ip:客户端的ip地址(cip) 目的地址:vip(代理服务器的外网地址) 2.当数据包到达我们的 代理服务器 源ip不变&#xff0c;需要修改目的ip及端口号 源ip:客户端的ip地址(c…

智慧城市中的数字孪生:构建城市管理的未来框架

目录 一、引言 二、数字孪生技术概述 三、数字孪生技术在智慧城市中的应用 1、实时监测与预警 2、模拟与优化 3、智能化决策 4、协同与共享 四、数字孪生技术构建城市管理的未来框架的价值 1、提高管理效率 2、优化资源配置 3、提升公共服务水平 4、增强应对突发事…

【Android开发】02-小费计算APP(Tip Time)

github地址&#xff08;项目中的A02_TipTime文件夹&#xff09;&#xff1a; https://github.com/tao355667/Android_Development 一、功能介绍 输入消费金额和服务满意度后&#xff0c;可计算出相应的小费(可选是否四舍五入)支持中英文系统可根据系统主题的明暗切换界面 二、…

SpringBoot源码解读与原理分析(四)SPI机制

文章目录 2.4 SPI机制&#xff08;Service Provider Interface&#xff09;2.4.1 JDK原生SPI1.定义接口实现类2.声明SPI文件3.测试 2.4.2 SpringFramework 3.2 的SPI1.声明SPI文件2.测试3.Spring SPI机制的实现原理 2.4 SPI机制&#xff08;Service Provider Interface&#xf…

【c++设计模式14】结构型6:享元模式(Flyweight Pattern)

【c设计模式14】结构型6&#xff1a;享元模式&#xff08;Flyweight Pattern&#xff09; 一、定义二、适用场景三、过程四、享元模式类图五、C示例代码六、使用注意事项 类型序号设计模式描述结构型1适配器模式&#xff08;Adapter Pattern&#xff09;它用于在不修改已有类的…

配置ssh连接Esxi、ESXi 收缩虚拟硬盘文件(.vmdk) 大小(回收ESXi thin磁盘空间)

文章目录 一、配置ssh连接Esxi1. Esxi开启ssh服务2. 如何设置ESXI主机启动时自动开启shell(ssh)服务 二、ESXi6.0中将虚拟机从厚置备转换为精简置备三、ESXi 收缩虚拟硬盘文件(.vmdk) 大小1. 三种虚拟磁盘类型2. 如何给ESXi 上的VM缩小硬盘&#xff08;VMDK&#xff09;回收ESX…

【C++精简版回顾】13.(重载1)运算符重载+,前置后置++

1.友元函数方式为类重载运算符 &#xff08;友元函数声明可以放在类任何地方&#xff09; 1.类 class MM { public:MM() {}MM(int grade,string name):grade(grade),name(name){}friend MM operator(MM object1, MM object2);void print() {cout << this->grade <…

单调队列的使用

单调队列其实就是一个队列&#xff0c;只是使用了一点巧妙的方法使得队列中的元素全都是单调递增&#xff08;或单调递减&#xff09;的 单挑队列主要解决以下问题&#xff1a; 滑动窗口在滑动时&#xff0c;r代表右侧数字进入串口&#xff0c;l代表左侧数字出窗口 这个过程…

Spring事件发布监听器ApplicationListener原理- 观察者模式

据说监听器模式也是mq实现的原理, 不过mq我还没来得及深入学习, 先用spring来理解一下吧 Spring事件发布监听器ApplicationListener原理- 观察者模式 什么是观察者模式一个Demo深入认识一下观察者模式Spring中的事件发布监听ps 什么是观察者模式 大家都听过一个故事叫做烽火戏…

数据结构与算法-希尔排序

引言 在计算机科学中&#xff0c;数据结构和算法是构建高效软件系统的基石。而排序算法作为算法领域的重要组成部分&#xff0c;一直在各种应用场景中发挥着关键作用。今天我们将聚焦于一种基于插入排序的改进版本——希尔排序&#xff08;Shell Sort&#xff09;&#xff0c;深…

证明高维度神经网络模型是低纬度神经网络模型的加和

神经网络中矩阵乘法的分解与应用 启发标题&#xff1a;神经网络中矩阵乘法的分解与应用摘要&#xff1a;引言&#xff1a;方法&#xff1a;实验&#xff1a;结论&#xff1a;参考文献&#xff1a;附录1附录2实验数据 启发 理论上 更具矩阵乘法 A[p,mn]B[mn,q]C[p,q] Acat(A[:,…

AAC ADTS格式

AAC⾳频格式&#xff1a;Advanced Audio Coding(⾼级⾳频解码)&#xff0c;是⼀种由MPEG-4 标准定义的有损⾳频压缩格式&#xff0c;由Fraunhofer发展&#xff0c;Dolby, Sony和AT&T是主要的贡献者。 ADIF&#xff1a;Audio Data Interchange Format ⾳频数据交换格式。这…

一次奇特的应急响应

访问polling.oastify.com 今天&#xff08;2024/3/5&#xff09;在深信服防火墙用户安全日志页面&#xff0c;检测到我的主机在和polling.oastify.com域名进行通信 当时通知我检查我的主机&#xff0c;慌得一批&#xff0c;检查完后可能认为是我代理的问题&#xff0c;把代理关…

w2v参数报错_TypeError: init() got an unexpected keyword argument ‘size‘

1.错误方式 w2v Word2Vec(docs,size16, sg1, window5, seed2020, workers24, min_count1, iter1) 在linux操作环境下&#xff0c;报错显示&#xff1a; TypeError: init() got an unexpected keyword argument ‘size’ 在vscode软件上&#xff0c;查看当前w2v参数 2.正确…

unocss 究竟比 tailwindcss 快多少?

unocss 究竟比 tailwindcss 快多少&#xff1f; 前言 我们知道 unocss 很快&#xff0c;也许是目前最快的原子化 CSS 引擎 (没有之一)。 unocss 解释它为什么这么快的原因&#xff0c;是因为它不用去解析 CSS 抽象语法树&#xff0c;直接在 content 里面通过正则表达式从内容…

yum 和 rpm

rpm说明 rpm -qa &#xff1a;列出所有已安装的软件包 [roothub ~] rpm -qa geoipupdate-2.5.0-1.el7.x86_64 ncurses-base-5.9-14.20130511.el7_4.noarch libndp-1.2-9.el7.x86_64 libfastjson-0.99.4-3.el7.x86_64 。。。 rpm -qf FILENAME &#xff1a;查找提供 FILENAME…

Nginx使用—http基础知识

web访问流程 当我们在客户端通过浏览器输入网址的时候&#xff0c;这时候是访问不到服务器的&#xff0c; 先会去找到DNS解析服务器&#xff0c;DNS解析服务器返回IP地址&#xff0c; 客户端通过http协议向服务端发送请求&#xff0c;服务器响应请求并返回对应的资源给客户端&a…

H5小游戏,斗地主

H5小游戏源码、JS开发网页小游戏开源源码大合集。无需运行环境,解压后浏览器直接打开。有需要的,私信本人,发演示地址,可以后再订阅,发源码,含60+小游戏源码。如五子棋、象棋、植物大战僵尸、开心消消乐、扑鱼达人、飞机大战等等 <!DOCTYPE html> <html> <…