在上一节中,为大家简明扼要的介绍了微软针对现代分布式系统在Azure上实现的相关服务组件。紧接上文内容,本节将为大家介绍Azure Service Fabric的基本概念及相关组件的工作机制, 包括Micro Service, Node type, Node等等。虽然名称叫Azure Service Fabric但其可应用的平台远不止Azure平台本身,我们会在后续章节的使用场景中为大家专门描述Service Fabric在各大平台上的工作形式。 Microsoft Azure Service Fabric是微软开发的一套支撑高可用高伸缩云服务的框架,其核心部分是一个分布式系统平台,用于构建可扩展的可靠应用。在便于封装可部署代码的同时,支持创建无状态和有状态的微服务,通过云平台来伸缩他们,来应对高复杂度、低延迟、数据密集的情况。开发者和系统管理员可以免于处理复杂的基础设施问题,将精力更多地投入到所构建应用程序的实现上。 微服务Microservice 在具体介绍Service Fabric之前,不得不先提一下微服务的思想。因为使用Service Fabric的开发过程就是微服务的设计开发过程。有了Service Fabric,您只需要考虑开发微服务的功能,而无需过多考虑部署后的伸缩性和可用性的问题,这些问题都可以交给Service Fabric来帮您实现。 微服务的思想就是将复杂单体式应用程序解耦成多个各个独立的服务,在功能不变的情况下,被分解出来的多个可管理的服务可以通过约定的接口相互通信。这种方法为采用单体式编码很难实现的功能提供了模块化的解决方案。因为,单个服务可以更易于开发、维护。这种架构方式使每个单个服务都可以有专门的团队来开发,每个团队可以各自选择自己擅长的开发技术,通过约定接口来实现相互通信。每个服务可以独立实现、测试、部署和升级,开发者不再需要担心其他服务部署对本服务的影响。AB测试加快了部署的速度,从而实现持续集成持续部署。所有微服务作为一个整体为用户提供服务,同时各个微服务可以根据自身对资源的需求独立扩展,从而最大化服务器的资源利用率。 回到Service Fabric, 一个Service Fabric开发的应用程序由数个服务组成,每个服务可以作为个体独自修改、扩展和管理,同时可以按照一个完整的应用程序来管理。Service fabric的设计目的就是用微服务的方式来简化构建复杂应用的过程。 集群Cluster 集群是一组通过网络连接的虚拟或者物理主机,您的微服务就部署在集群中,集群的大小可以扩展到上千台主机。 节点Node 集群中的一台机器或者VM称为Node, 每个Node会被分配一个名称(string字符串)。Node还有其他一些属性,比如位置属性placement properties。可以通过每台机器或者VM都有一个自启动Windows系统服务FabricHost.exe,它随系统启动后会执行另外两个程序:Fabric.exe 和 FabricGateway.exe, 这两个程序就组成了一个完整的Node。出于测试目的,有时单台机器上也可以通过运行多个Fabric.exe 和 FabricGateway.exe的实例来拥有多个Node。 一个集群中的所有Node相互之间平等且可以直接互相通信。Node除了宿主在物理主机或VM中,还可以宿主在基于Windows的Docker容器中、本地部署的服务器中、其他公有云和私有云中,我们会在后续Service Fabric的使用场景中为大家详细介绍这一内容。 应用程序Application:Application Type和Service Type Service Fabric应用程序(Application)是一组服务(service)的集合,其中一个service是为Application提供指定功能的单元。您将通过定义一个Application Type和对应的几个Service Type来构建一个Service Fabric的Application. 当Application被部署到Service Fabric Cluster里面时,这些类型会被相应地初始化成application实例和service实例。这里类似我们OO地思想。 Application Type和Named Application: Application Type包含一组Service Type的集合,对应上文中的Service Fabric应用程序(Application)是一组服务(service)的集合。 Application Type的name和version定义在ApplicationManifest.xml文件中。在部署的时候,ApplicationManifest.xml会被拷贝到Service Fabric的image store中。通过在Cluster中创建Named Application来初始化Application的实例。Named Application通过"fabric:/MyNamedApp"的形式来命名。 Service Type和Named Service: Service Type的name和version定义在ServiceManifest.xml文件中。当创建好一个Named Application后,就可以创建Named service. 例如您在 "MyNamedApp" Named Application中创建一个 "MyDatabase" Named Service, Name Service被命名为 "fabric:/MyNamedApp/MyDatabase". 分区Partitions和复制replicas […]
View Details在上一节中,我们大致了解了分布式系统的整体架构。简而言之,因为单台机器性能总是有限(摩尔定律增长性能速率无法满足实际应用场景的增速),系统架构师通过各种方式将来自用户的请求分散至多个服务系统和服务器协同完成。 而在现今最火热的云时代,微软已经从云服务层面整体解决了所有分布式系统需要考虑和实现的难题。 下面我们将粗粒度介绍微软云Azure中所有和上一节各个环节相关的服务组件。我们会大致介绍其功能,并且在后续章节中详细介绍其使用方法。 动态DNS —— Azure Traffic Manager (ATM) https://azure.microsoft.com/en-us/services/traffic-manager/ 在上一节中,我们了解用户首先通过域名来获得服务器的IP入口。 同时我们也已经知道动态域名可以从地域靠近,线路优化,负载均衡IP等多种方式来解决其他服务无法达到的网络物理环境优化。 Azure Traffic Manager就是这样一个动态DNS解决方案。 最终用户请求业务域名 –> 域名CNAME映射至ATM域名 –> ATM根据配置从多个endpoint域名中返回一个作为其CNAME 我们可以通过如下方式来配置和指定Azure Traffic Manager的工作行为。 创建一个Azure Traffic Manager,从而得到一个ATM域名,类似 xxx.trafficmanager.windows.net。 将ATM域名作为自己域名(例如:www.contoso.com)的CNAME进行绑定,从而实现对最终用户屏蔽ATM域名的效果。 在ATM中配置多个endpoint站点域名,作为动态DNS目标结果。 配置ATM工作模式:Priority (failover 模式), Performance, Weighted Priority:ATM探针会定时探测所有endpoint站点是否可用,如果站点失效,自动将域名切换至下一个endpoint。 Performance:ATM全球探针会定时探测所有endpoint到全球各个主要网络节点的响应速度。并且定时记录并刷新该速度列表。当最终用户进行DNS解析请求时,该列表会作为参考标准返回对应最终用户性能最快的一个endpoint域名。 Weighted:在配置endpoint时进行权重配置,ATM会根据权重在解析时按不同权重比例返回结果。例如70%的时间返回endpoint A域名,另外其余时间返回endpoint B域名。 通过以上配置,Azure帮助架构师从域名层面进行了第一次负载均衡处理。 网络负载均衡 —— Azure Load Balancer (ALB) https://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-overview 在上文中,ATM作为第一层系统,将业务域名最终映射到了endpoint域名。 从网络DNS角度考虑,endpoint域名最终必定是一个公用IP的ANAME。 但是我们知道,IP只是作为网络连接的接入地址,它和真正处理服务的服务器没有必然相关性。 因此在Azure中,从endpoint域名->IP->服务器之间又可以做如下拆分工作,事实上Azure Service Fabric也是这样做的。 创建Azure Virtual Machine Scale Set (我们会在本节下文讲到VMSS,在此你可以先简单理解为这是一个VM集群,可以进行一些统一的对外IP配置) 为VMSS配置一个公共的IP及Azure子域名,例如:207.46.154.78 / xxx.eastasia.cloudapp.azure.com 为该公共IP创建ALB,配置以下信息 IP池,用来告知ALB需要将请求负载均衡至VMSS中的多少台VM的IP列表。 端口映射,将公开端口映射至VMSS中具体每台VM监听的端口号。例如 207.46.154.78:80 –> 192.168.1.3:8080 探针策略,配置ALB如何探测后台IP端口是否可用,以免负载均衡至不可用服务器 根据以上配置,所有请求至 xxx.eastasia.cloudapp.azure.com 域名后都会经由ALB转发至真正的VM。 虚拟机扩展集群 —— Azure Virtual […]
View Details作者:潘罡 (Van Pan) @ Microsoft 在正式介绍Service Fabric之前,我们认为应该首先介绍分布式系统的经典架构。 理解了分布式系统的演进过程可以极大程度上帮助理解Service Fabric以及Azure服务中所有针对分布式系统的优秀产品。 简单系统模型 在IT时代初期,如果需要自行构建一个系统,需要完成以下工作。 采购服务器 在服务器中安装Web服务器 在服务器中安装数据库 向ISP申请静态IP 向服务器部署静态IP 向服务器中部署网站 向服务器中部署数据库原始数据 向域名供应商购买域名 将域名和静态IP进行绑定 向证书供应商购买证书 向服务器中部署证书 对Web服务器配置证书,监听域名等 网站启动外部服务监听,比如HTTP,HTTPS 经典分布式模型 随着网站访问量逐渐增加,系统压力逐渐上升。 此时根据实际情况不同,会对站点服务器做以下调整。 使用性能更好的服务器,简称垂直升级。该做法已经不是主流做法,除非在无法实现下列解决方案前提下才会考虑。 数据库迁移至单独服务器。 数据库水平升级 数据库主从分离,读写分离。使用单独服务器作为写服务器,其他服务器作为读服务器。成熟数据库都可以配置主从分离。 数据库垂直拆分。将数据库数据不同的表放到不同的服务器。 数据库水平拆分。将数据库表根据特征拆分至不同表。比如2016年数据和2017年数据分表存储。 Web服务器垂直拆分,将子系统拆分至单独服务器 Web服务器负载均衡,有以下几种做法 动态域名解析 将服务器放置在不同物理地域。比如北京上海两台服务器分别针对华南华北用户。对于同一个域名,华南华北用户解析到的服务器IP不同。 同一台服务器,不同ISP线路优化。有些机房有电信联通双线。网站管理员申请电信联通不同IP,用户在电信联通环境下针对同一个域名解析到不同IP。 同域名多IP负载均衡。即使是同一个ISP,同一个机房的服务器,也可以通过动态域名解析返回多个不同IP。用户的请求会在不同IP间切换,同样达到了负载均衡效果。 网络负载均衡 硬件负载均衡。商业负载均衡服务器,例如F5。从硬件层面将网络连接负载均衡至不同后台Web服务器。 软件负载均衡。现在有大量开源反向代理服务器,例如Nginx。使用该服务可以在前端监听端口,并且将请求分发至后台的不同服务器。 当服务器面临突发的请求压力(可能是被DDos攻击,也可能是因为业务营销活动,比如双十一),客户开始电话轰炸站点卡死不可用,如何快速解决问题? 如果发现是数据库压力过大,应该怎么办? 对数据库进行拆分吗? 这几乎是不可能的,因为数据库的任何改动都会反向影响代码修改。而且拆分数据库需要大量的时间。 比较可行的解决方案,有以下几种。 部署新的读数据库服务器,减少当前数据库服务器承担的并发压力 关闭一部分线上功能,减少数据库整体请求 当然最完美的解决方案,就是数据库设计本身就是针对分布式的。 如果数据库也可以动态扩容,就不会遇到数据库性能瓶颈。 如果发现是Web服务器压力过大,应该怎么办? 最行之有效的方法就是通过网络负载均衡添加服务器。 但这又引入了另一个问题。 通常情况下,Web服务器的性能瓶颈通常都是由某个部件导致的,仅仅针对这个组件,就需要部署一整套Web服务,看起来非常不合理。 因为现在服务器压力很大,所以完全不知道需要部署多少台服务器才够支撑。 每台服务器都需要做相同的部署操作,简陋一点是每台都需要人工操作,高级一些是部署脚本,但是因为新增加了服务器,都需要修改负载均衡配置。 如果有某种解决方案,可以准确定位性能瓶颈组件,并且在服务器自动增加后自动扩展该组件,就可以同时解决自动化以及经济性需求。 在下一节中,我们将会详细介绍在现在的云服务环境中,分布式系统的演进以及系统架构师对于分布式系统更深的理解。 在掌握了云时代分布式系统的最新概念后,才能理解Service Fabric中所有抽象概念以及使用场景。 from:http://www.cnblogs.com/mschiefevangelist/p/6358788.html
View Detailsservlet是一个好东西,有时候虽然麻烦,但是有时开发过程中对外提供http接口,还是比较方便的。 但是返回对方数据时,如果包含中文,那就可能会遇到中文乱码问题。 返回数据一般使用PrintWriter 首先需要知道对方的编码格式。 然后在返回代码里写下下面两句。 protected void doPost(HttpServletRequest request, HttpServletResponse resp) ……………. resp.setCharacterEncoding("utf-8"); resp.setContentType("text/html;charset=utf-8"); …………… PrintWriter printWriter = resp.getWriter(); printWriter.write("中文"); printWriter.close(); from:https://blog.csdn.net/baidu_18607183/article/details/78646131
View Details问题描述 用Eclipse创建Maven结构的web项目的时候选择了Artifact Id为maven-artchetype-webapp,由于这个catalog比较老,用的servlet还是2.3的,而一般现在都是用3.0,在Project Facets里面修改Dynamic web module为3.0的时候就会出现Cannot change version of project facet Dynamic web module to 3.0,如图: 解决这个问题的步骤如下: 1. 把Servlet改成3.0,打开项目的web.xml <?xmlversion="1.0"encoding="UTF-8"?> <web-appxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="schedule-console"version="3.0"> 2. 修改项目的设置,在Navigator下打开项目.settings目录下的org.eclipse.jdt.core.prefs 把1.5改成1.8 eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.source=1.8 3. 打开org.eclipse.wst.common.project.facet.core.xml 把java改为1.8, 把jst.web改为3.0; <?xmlversion="1.0"encoding="UTF-8"?> <faceted-project> <fixedfacet="wst.jsdt.web"/> <installedfacet="jst.web"version="3.0"/> <installedfacet="wst.jsdt.web"version="1.0"/> <installedfacet="java"version="1.8"/> </faceted-project> OK,搞定了。 from:https://www.cnblogs.com/strinkbug/p/4939299.html
View Details了解如何在数分钟内在 Windows 上部署你的第一个适用于 .NET 的 Azure Service Fabric 应用程序。 完成后,你会有一个本地群集,与 Reliable Services 应用程序一起运行。 先决条件 开始之前,请确保已设置开发环境。 此过程包括安装 Service Fabric SDK 和 Visual Studio 2017 或 2015。 创建应用程序 以管理员身份启动 Visual Studio。 创建一个项目,方法是选择 Ctrl+Shift+N。 在“新建项目”对话框中,选择“云” > “Service Fabric 应用程序”。 将应用程序命名为“MyApplication”, 然后选择“确定”。 可以在下一对话框中创建任何类型的 Service Fabric 应用程序。 对于本快速入门,请选择“.Net Core 2.0” > “有状态服务”。 将服务命名为“MyStatefulService”, 然后选择“确定”。 Visual Studio 会创建应用程序项目和有状态服务项目, 然后在解决方案资源管理器中显示它们。 应用程序项目 (MyApplication) 没有任何代码。 而是引用一组服务项目。 它还有三个其他类型的内容: 发布配置文件 部署到不同环境所需的配置文件。 脚本 用于部署或升级应用程序的 PowerShell 脚本。 应用程序定义 在 ApplicationPackageRoot 下添加说明应用程序组合情况的 ApplicationManifest.xml 文件。 关联的应用程序参数文件位于 ApplicationParameters 下,这些文件可以用来指定特定于环境的参数。 Visual Studio 选择在关联的发布配置文件中指定的应用程序参数文件。 有关服务项目的内容概述,请参阅 Reliable Services 入门。 部署和调试应用程序 有了应用程序以后,即可通过以下步骤运行、部署和调试它。 在 Visual Studio 中选择 F5,部署要调试的应用程序。 如果出现一个消息框,请求授予“ServiceFabricAllowedUsers”组对Visual Studio 项目目录的读取和执行权限,请单击“是”。 备注 首次在本地运行和部署应用程序时,Visual Studio 会创建用于调试的本地群集。 这可能需要一些时间。 群集创建状态显示在 Visual Studio 输出窗口中。 群集准备就绪时,将从 SDK 随附的本地群集系统托盘管理器应用程序收到通知。 […]
View Details参考 微软官方文档 service fabric 百家号 大话微服务架构之微服务框架微软ServiceFabric正式开源 一、概述 1.概念 Azure Service Fabric 是一款分布式系统平台,可方便用户轻松打包、部署和管理可缩放的可靠微服务和容器。 Service Fabric 还解决了开发和管理云本机应用程序面临的重大难题。 开发人员和管理员不需解决复杂的基础结构问题,只需专注于实现苛刻的任务关键型工作负荷,即那些可缩放、可靠且易于管理的工作负荷。 Service Fabric 代表了下一代平台,用于生成和管理在容器中运行的企业级单层云规模应用程序。 2.微服务 微服务是指用小型服务集合来构建服务端应用的方法,每个服务在独立的进程中运行,服务间通过特定协议(http,AMQP)通信,每个服务能够独立开发、部署,拥有自己的领域数据模型和领域逻辑,可以有不同的数据存储技术甚至是不同的编程语言。 微服务的目的在:解耦。解耦是永恒的主题,依赖注入是为了解耦,应用分层是为了解耦,这些可以看做是纵向解耦,而微服务是把应用横向解耦,服务间解耦。 下图是传统一体式应用开发与微服务开发的对比: ①单一式应用包含域特定的功能,通常按照功能层来划分,例如传统三层。 ②单一式应用可通过复制到多个服务器/虚拟机/容器上进行扩展。 ③微服务应用程序将单个功能分隔成单个较小的服务。 ④微服务方法可通过独立部署每个服务而扩展,跨服务器/虚拟机/容器创建这些服务的实例。 service fabric 从三方面来帮助我们使用微服务的方式来构建应用: ①提供系统服务的平台,用于部署、升级、检测和重启失败的服务、发现服务、路由消息、管理状态和监视运行状况 ②能够部署在容器中运行或作为进程运行的应用程序。 ③有助于以微服务形式生成应用程序的生产编程 API:ASP.NET Core、Reliable Actors 和 Reliable Services。 可以选择使用任意代码来生成微服务。 但使用这些 API 不仅可让作业变得更简单,也能更深入地与平台集成。 例如,可以获取运行状况和诊断信息,或利用内置的高可用性 下图是service fabric 与spring cloud 的对比: 二、应用场景 1.高可用服务:Service Fabric 服务通过创建多个辅助服务副本提供快速的故障转移。 节点、进程或单独的服务因硬件或其他故障而不可用时,其中一个辅助副本会提升为主副本,将对服务的损失降到最低。 2.可缩放服务:可对单独的服务进行分区,以允许在群集范围内扩大状态。 此外,还可以动态创建并删除单独的服务。 服务可以快速简单地从几个节点上的几个实例扩大到多个节点上的数千个实例,并再次减少,具体取决于资源需求。 可以使用 Service Fabric 来生成这些服务并管理其整个生命周期。 3.基于回话的交互式应用:在应用程序(例如在线游戏或即时消息)需要低延迟读取和写入时,Service Fabric 非常有用。 Service Fabric 使你能够生成这些交互式的有状态应用程序,而无需创建一个无状态应用所需的单独存储或缓存。 (这会增加延迟时间并可能产生一致性问题)。 4.数据分析和工作流:Service Fabric 的快速读取和写入使必须可靠处理事件或数据流的应用程序成为可能。Service Fabric 还可让应用程序描述处理管道,其中的结果必须能够可靠地传递到下一个处理阶段而不会丢失。这包括交易和财务系统,其中的数据一致性和计算保证至关重要。 三、开发准备 1.Windows下开发环境准备 如果需要在windows上开发并运行service fabric 应用程序,需要安装Service Fabric 运行时、SDK 和工具 具体安装步骤可参照 Windows上安装service fabric 以下是windows 10 下,安装了vs2017的开发人员的环境准备 ①重新运行vs2017安装软件,选择修改,选择azure开发 ②安装 Microsoft Azure […]
View DetailsAMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等条件的限制。Erlang中的实现有 RabbitMQ等。
View Detailsstring类型转成byte[]: byte[] byteArray = System.Text.Encoding.Default.GetBytes ( str ); byte[]转成string: string str = System.Text.Encoding.Default.GetString ( byteArray ); string类型转成ASCII byte[]: ("01" 转成 byte[] = new byte[]{ 0x30,0x31}) byte[] byteArray = System.Text.Encoding.ASCII.GetBytes ( str ); ASCIIbyte[]转成string: (byte[] = new byte[]{ 0x30, 0x31} 转成"01") string str = System.Text.Encoding.ASCII.GetString ( byteArray ); byte[]转16进制格式string: new byte[]{ 0x30, 0x31}转成"3031": publicstaticstring ToHexString ( byte[] bytes ) // 0xae00cf => "AE00CF " {string hexString = string.Empty; if ( bytes != null ) { StringBuilder strB = new StringBuilder (); for ( int i = 0; i < bytes.Length; i++ ) { strB.Append ( bytes[i].ToString ( "X2" ) ); } hexString = strB.ToString (); }return hexString; } 16进制格式string 转byte[]: publicstaticbyte[] GetBytes(string hexString, outint discarded) { discarded = 0; string newString = ""; char c;// remove all none A-F, 0-9, charactersfor (int i=0; i<hexString.Length; i++) { c = hexString[i];if (IsHexDigit(c)) newString += c; else discarded++; }// if odd number of characters, discard last characterif (newString.Length % 2 != 0){ discarded++; newString = newString.Substring(0, newString.Length-1); } int byteLength = newString.Length / 2;byte[] bytes = newbyte[byteLength];string hex;int j = 0;for (int i=0; i<bytes.Length; i++){ hex = new String(new Char[] {newString[j], newString[j+1]}); bytes[i] = HexToByte(hex); j = j+2; } return bytes; } from:https://www.cnblogs.com/Maxq/p/5953682.html
View Details一、RabbitMQ 基础理解 RabbitMQ,是一个使用 erlang 编写的 AMQP(高级消息队列协议)的服务实现,简单来说,就是一个功能强大的消息队列服务。 概念理解: Producer: 消息发送者 RabbitMQ: Vhost: 相当于分组,每个vhost下数据是隔离的 Exchange: 路由器,接收消息,本根据RoutingKey分发消息 headers:消息头类型 路由器,内部应用 direct:精准匹配类型 路由器 topic:主题匹配类型 路由器,支持正则 模糊匹配 fanout:广播类型 路由器,RoutingKey无效 RoutingKey: 路由规则 Queue: 队列,用于存储消息(消息的目的地) Consumer: 消息消费者 持久化: 一个好的消息队列当然需要消息持久化功能,服务宕机,未消费消息不丢失,RabbitMQ持久化分为Exchange、Queue、Message Exchange 和 Queue 持久化 指持久化Exchange、Queue 元数据,持久化的是自身,服务宕机,Exchange 和 Queue 自身就没有了 Message 持久化 顾名思义 把每一条消息体持久化,服务宕机,消息不丢失 Durable 持久、Transient 临时,Queue新建类似 分析理解: 便于更直观的理解,把 RabbitMQ 的消息流对比与Http Rest接口更家熟悉形象 www.xxx.com/webappPath/trade/getOrder -> getOrder(message) GET RabbitMQ Server:同比 域名 www.xxx.com,只有通过域名才能到达 Server Vhost:同比 /webappPath,一个域名可能指向多个app Exchange:同比 /trade,trade/* 下有多个method,但是需要先到达这个Class RoutingKey:同比 /getOrder,只有完成的 URL 才是有效的,才能确定到具体的方法 Queue:同比 getOrder(message) 消息的最终目的地 Exchange Type: 同比 GET,但是Rest MethodType是整个URL的Type,而不是 Queue 以上只是为了更好理解,千万不要混淆 Producer / Consumer 就很好理解了,基于AMQP协议链接RabbitMQ Server,发送消息 / 接收消息 二、RabbitMQ 消息确认策略分析 Confrim / Transaction 概念应用 RabbitMQ 提供了两种可靠性的确认策略 Confrim / Transaction,Producer […]
View Details