如何让普通变量也支持事务回滚?
有一次和人谈起关于事务的话题,谈到怎样的资源才能事务型资源。除了我们经常使用的数据库、消息队列、事务型文件系统(TxF)以及事务性注册表(TxR)等,还有那些资源直接可以纳入事务进行状态的管理呢?我说如果我们按照.NET事务模型的规范对相应的资源进行合理的封装,原则上我们可以让任何可编程的资源成为事务型资源。本篇文章中,我将通过简单的编程将一个普通的变量变成支持事务,让变量的值也可以回滚,以确保事务前后的数据一致性。一、什么是事务型的变量本文中所说的事务型变量指的是这样的变量:在事务开始前,变量的初始值会被保存;在事务中对变量的赋值只有在事务被成功提交后才会真正赋值给变量;如果事务中止导致回滚,变量的值将会恢复到事务开始之前的状态。上面的对事务型变量的描述可以通过下面的程序来体现:变量v在初始化时被赋值为1。然后通过TransactionScope开始一个事务,并将变量纳入该事务之中。在事务范围内将值赋值为2,然后调用DoSomething方法,并提交事务。如果DoSomething执行过程中抛出异常,整个事务将会回滚。当整个事务中止回滚
Shifter: 面向高性能计算的容器
容器技术是一种操作系统层的虚拟化技术。它通过命名空间和Cgroup进行资源的隔离和控制,共享操作系统内核,分享系统资源。相比虚拟机,容器提供了一种更轻量级的虚拟化技术,它具有更高的资源利用率和更快的执行性能。Docker作为一种容器技术,引入了应用镜像管理机制,适应快速的软件开发,部署和维护,推动了容器技术的普及和发展。Shifter容器的介绍用于高性能计算的容器在高性能计算领域,应用软件通常有大量的系统依赖和复杂的环境配置:各种的软件包,不同版本的库和操作系统的发布版本等。这让系统的部署和维护都面临巨大的挑战。传统的虚拟化技术可以解决部署和维护的问题,但是由于在计算上增加了额外的虚拟化负载,无法最大化利用机器的物理资源用于有效计算。而容器技术可以解决这些问题。Docker的镜像管理机制可以帮助用户将复杂的软件环境打包,便于管理和维护。容器的轻量级隔离性增强了系统的安全,而不会降低系统的计算性能。尽管如此,Docker容器在高性能计算领域的采用也存在一些问题。Docker的资源管理功能与集群管理软件的功能有重叠,Docker
Kafka 源码分析之网络层(二)
上一篇介绍了概述和网络层模型实现《Kafka源码分析之网络层(一)》,本编主要介绍在Processor中使用的nioselector的又一封装,负责具体数据的接收和发送。PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!对nio的封装:Selector类所在文件:clients/src/main/java/org/apache/kafka/commmon/network/Selector.java源码中的注释:AnioSelectorinterfacefordoingnon-blockingmulti-connectionnetworkI/O.ThisclassworkswithNetworkSend}andNetworkReceivetotransmitsize-delimitednetworkrequestsandresponses.重要函数解析:(1)register(Stringid,SocketChannelsocket
每日一博 | 消息中间件集群部署、测试与应用
业务系统中,通常会遇到这些场景:A系统向B系统主动推送一个处理请求;A系统向B系统发送一个业务处理请求,因为某些原因(断电、宕机。。),B业务系统挂机了,A系统发起的请求处理失败;前端应用并发量过大,部分请求丢失或后端业务系统卡死。。。。这个时候,消息中间件就派上用场了--提升系统稳定性、可用性、可扩展性。一、消息中间件消息队列技术是分布式应用间交换信息的一种技术。消息队列可驻留在内存或磁盘上,队列存储消息直到它们被应用程序读走。通过消息队列,应用程序可独立地执行--它们不需要知道彼此的位置、或在继续执行前不需要等待接收程序接收此消息。总体来说,消息中间件有以下作用:降低耦合、流量消峰(防浪涌)、可靠性传输、事件驱动1.降低耦合:通过发布订阅的方式松耦合我们以注册业务为例,注册成功会发送短信、邮件给用户来确认,传统架构模型是这样:邮件业务和短信业务的代码是写在用户注册的流程里,无论是通过接口的方式来实现,还是远程调用的方式来实现,耦合度都很高,现在,新增一个需求,用户注册完成以后不发送邮件了,而是给用户“增加积分”,我们来
Android 消息机制(一)消息队列的创建与循环的开始 Looper与MessageQueue
本文基于Android7.1.1(API25)的源码分析编写与之前的触摸事件分发机制分析的文章一样,Android系统机制的分析中关键的一环就是事件消息的处理。之前也说过,Android本质上是一个事件驱动的模型,通过各式各样不断产生事件消息的来推动UI、数据的更新与对我们交互的反馈,没有事件消息的产生,就不会有直观的界面的变化,也就不会有应用丰富的功能。所以Android的消息机制与其他过程的关系是极其紧密的,例如启动Activity的过程就涉及到ActivityManagerService与应用主进程的通信,产生的通知消息通过Binder机制送入应用主进程的消息队列,再由主进程的消息循环来读取这一消息来进行处理。之前触摸事件分发中也是利用了应用主进程的消息队列来读取我们的触摸事件再进行后续的分发处理。可以说消息队列在各种通信过程中无处不在。消息队列的存在为异步处理提供了一个非常好的基础,有了消息队列之后,我们就可以在新的线程中处理计算、IO密集、阻塞的任务而不会影响UI的更新,在处理过程中可
《RabbitMQ官方指南》RPC
远程过程调用(RPC)(Java客户端版)在第二章(工作队列WorkQueues)中,我们学习了如何使用工作队列在多用户之间分配耗时的任务。但是如果我们需要在远程电脑上运行一个函数方法,并且还要等待一个返回结果该怎么办?好吧,这将会是一个不一样的故事。这种模式通常被我们称为远程过程调用或者RPC.在本章教程中,我们将会学习使用RabbitMQ去搭建一个RPC系统:一个客户端和一个可以升级(扩展)的RPC服务器。由于我们没有任何的值得分配的耗时的任务,所以我们将创建一个返回斐波那契数列的虚拟的RPC服务。客户端接口(Clientinterface)为了说明如何使用去使用一个PRC服务,我们将创建一个简单的客户端类。它将暴露一个命名为call的方法,这个方法发送一个阻塞的PRC请求,直到收到一个响应的回复:FibonacciRpcClientfibonacciRpc=newFibonacciRpcClient();Stringresult=fibonacciRpc.call("4");System.out.
《RabbitMQ官方指南》路由
Routing在上一节我们建立了一个简单的日志系统,已经能够传播日志信息给接收者了。在这一节我们将给它增加一个特性-订阅部分消息。比如说,我们能够从控制台打印的所有日志信息中将至关重要的错误信息指向日志文件(保存在硬盘里)。Bindings在前面的例子中我们已经创造了bindings,你可以这样调用它channel.queueBind(queueName,EXCHANGE_NAME,"");一个bindings就是queue和exchange之间的一种映射关系(多对多关系),将queue绑定到exchange上,也可以这样理解:queue对来自此exchange的消息感兴趣(传递消息)。Bindings创建的时候也可以同时附带一个额外的名为routingKey的参数,为了避免与basic_publish参数混淆,我们把他叫做bindingkey.我们可以这样创建一个带有bindingkey的bindings。channel.queueBind(queueName,EXCHANGE_NAME,"
MQTT——控制报文格式
解控制报文格式是学习MQTT中,笔者认为最为重要的一个知识点。MQTT的所有行为都离不开他。控制报文可以分为三个部分组成,分别为:固定报头、可以变报头、有效载荷部分。注意:上面的说的报文的类型。是指连接(CONNECT),发布(PUBLISH)等。而等级是指服务质量(QoS)。固定报头固定报头,从官方的说明文档指出他又边俩部分。可是还是喜欢把他说明成三个部分。如下控制报文的类型:用于标示类型,如:连接(CONNECT)报文,发布(PUBLISH)报文等。他占了四个字节。如:连接报文对应二进制:0001。控制报文类型的标志位:这里包含的内部比较多。分别为:标示发送重复数(DUP)(1字节)、服务质量(QoS)(2字节)、保留标志(RETAIN)(1字节)。同样子他也占了四个字节剩余长度:和字面意思一样子。只是笔者看了文档说明,有一点不明白。笔者以为就是可变报头和有效载荷部分的长度。他占8个字节。上面有讲到关于发送重复数(DUP)。这个主要是关系到服务质量(QoS)的设置。如果只是设置为0的话,那么发
Kafka 不只是个消息系统
Confluent联合创始人兼CEOJayKreps发表了一篇博文,给出了Kafka的真正定位——它不只是个消息系统,它还是个存储系统,而它的终极目标是要让流式处理成为现代企业的主流开发范式。以下内容翻译自作者的博文,查看原文It’sOkayToStoreDataInApacheKafka。人们总是问是否可以把Kafka作为长期的数据存储来使用,很显然,如果把数据保留策略设置为“永久”或者启用主题的日志压缩功能,那么数据就可以被永久保存下来。但我觉得人们其实真正想知道的是,这样做是不是很疯狂。简而言之,这样做不算疯狂。实际上,人们一直都在这么做,而且Kafka的设计意图之一就是要将它作为数据存储系统。不过问题是,为什么我们要把Kafka作为数据存储呢?你可能在构建一个基于事件溯源的应用程序,需要一个数据存储来保存变更日志。理论上,你可以使用任何一种存储系统。Kafka已经解决了不可变(immutable)日志和基于这些日志生成“物化视图”的问题,既然这样,为什么不直接使用Kafk
每日一博 | SpringBoot JMS (ActiveMQ) 使用实践
ActiveMQ1.下载windows办的activeMQ后,在以下目录可以启动:2.启动后会有以下提示3.所以我们可以通过http://localhost:8161访问管理页面,通过tcp://localhost:61616来连接消息服务器,用到的用户名和密码都在以下文件中(默认为admin=admin)springboot连接ActiveMQ1.加入依赖:spring-boot-starter-activemq2.配置连接属性:spring.activemq.broker-url=tcp://localhost:61616spring.activemq.user=adminspring.activemq.password=adminspring.activemq.pool.enabled=false消息的发送和接收生产者/消费者模式1.创建生产者packagecom.example.demo8activemq.jms;importorg.apache.activemq.command.A
Docker下的Kafka学习之三:集群环境下的java开发
在上一章《Docker下的Kafka学习之二:搭建集群环境》中我们学会了搭建kafka集群环境,今天我们来实战集群环境下的用java发送和消费kafka的消息;环境规划本次实战我们要搭建的环境略有一些复杂,整体环境如下图:如上图所示,从浏览器发起一个请求会经历以下历程:1.请求到nginx后,由nginx转发到tomcat,nginx后面接了两个tomcat,容器名分别是producer1和producer2,部署的都是kafkaclusterproducerdemo这个应用的war包;2.producer1和producer2收到消息后,向broker投递消息;3.consumer1、consumer2、consumer3是三个tomcat,上面都部署了kafkaclusterconsumerdemo这个应用,连接了kafka的partition,收到消息后消费这些消息,这三个consumer属于同一个group,共同消息主题”test002”的消息;整个环境的ip和功能说明列表如下:
网络抓包学MQTT物联网协议
作者:Gitbook-冰尘MQTT(MessageQueueTelemetryTransport),翻译成中文就是,遥测传输协议,其主要提供了订阅/发布两种消息模式,更为简约、轻量,易于使用,特别适合于受限环境(带宽低、网络延迟高、网络通信不稳定)的消息分发,属于物联网(InternetofThing)的一个标准传输协议。MQTT协议的设计思想是开放、简单、轻量、易于实现。现在国内很多企业都已经广泛使用MQTT作为手机客户端与服务器端推送消息的协议,除此之外,由于其协议的特别针对受限环境(带宽低、网络延迟高、网络通信不稳定),在物联网(InternetofThing)应用中已经大展拳脚,因为很多物联网的设备都是一些计算和储存能力受限的嵌入式设备。那么应该如何学习这个协议呢?笔者提供了一种深入浅出的方法,通过使用WireShark进行网络抓包,结合真实存在网络字节,深入其中,来一场栩栩如生的学习体验。另作者为了照顾没有基础背景的读者,将会安装下面的顺序循序渐进的进行说明和分享。一、为什么使用MQTT协
celery rabbit mq 详解
Celery介绍和基本使用Celery是一个基于python开发的分布式异步消息任务队列,通过它可以轻松的实现任务的异步处理,如果你的业务场景中需要用到异步任务,就可以考虑使用celery,举几个实例场景中可用的例子:1)你想对100台机器执行一条批量命令,可能会花很长时间,但你不想让你的程序等着结果返回,而是给你返回一个任务ID,你过一段时间只需要拿着这个任务id就可以拿到任务执行结果,在任务执行ing进行时,你可以继续做其它的事情。2)你想做一个定时任务,比如每天检测一下你们所有客户的资料,如果发现今天是客户的生日,就给他发个短信祝福Celery在执行任务时需要通过一个消息中间件来接收和发送任务消息,以及存储任务结果,一般使用rabbitMQorRedis,后面会讲1.1Celery有以下优点:简单:一单熟悉了celery的工作流程后,配置和使用还是比较简单的高可用:当任务执行失败或执行过程中发生连接中断,celery会自动尝试重新执行任务快速:一个单进程的celery每分钟可处理上百万个任务灵
使用spark-streaming实时读取Kafka数据统计结果存入MySQL
在这篇文章里,我们模拟了一个场景,实时分析订单数据,统计实时收益。场景模拟我试图覆盖工程上最为常用的一个场景:1)首先,向Kafka里实时的写入订单数据,JSON格式,包含订单ID-订单类型-订单收益2)然后,spark-streaming每十秒实时去消费kafka中的订单数据,并以订单类型分组统计收益3)最后,spark-streaming统计结果实时的存入本地MySQL。前提条件安装1)spark:我使用的yarn-client模式下的spark,环境中集群客户端已经搞定2)zookeeper:我使用的是这个集群:10.93.21.21:2181,10.93.18.34:2181,10.93.18.35:21813)kafka:我使用的是standalone模式:10.93.21.21:90934)mysql:10.93.84.53:3306语言python:pykafka,pipinstallpykafkajava:spark,spark-streamin
Handler的整理
Message消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。MessageQueue消息队列,用来存放通过Handler发布的消息,按照先进先出执行。Handler有俩用途:1、用于子线程与主线程之间的通讯2、用于向子线程发出消息请求。Handler是Message的主要处理者,是Android提供的一套ui处理机制,负责将Message添加到消息队列以及对消息队列中的Message进行处理。Looper循环器,扮演MessageQueue和Handler之间桥梁的角色,循环取出MessageQueue里面的Message,并交付给相应的Handler进行处理。线程UIthread通常就是mainthread,而Android启动程序时会替它建立一个MessageQueue。异常Onlytheoriginalthreadthatcreatedaviewhi
《RabbitMQ官方指南》主题
Topics在上一个教程中,我们改进了我们的日志系统而不是使用只能进行广播的fanout交换类型,我们使用direct类型,能够选择性地接收日志。虽然使用direct交换类型改进了我们的系统,但它仍然有限制–它不能基于多条件进行路由选择。在我们的日志记录系统中,我们可能不仅要根据日志级别订阅日志,还可以基于日志源进行订阅。您可能会从syslogunix工具中了解过这个概念,该工具可以根据日志级别(info/warn/crit..)和设备(auth/cron/kern…)来路由日志。这将给我们很大的灵活性–我们可能只想要监听来自“cron”的重要错误,但是想监听来自”kern“的所有日志。要在我们的日志系统中实现这一点,我们需要了解一个更复杂的交换类型-Topic(主题)交换。主题交换发送到主题交换区的消息不能是任意的routing_key–它必须是由点分隔的单词列表。这些单词可以是任何东西,但通常它们指定与消息相关联的一些功能。几个有效的路由密钥示例:“stock.usd.nyse”,“nyse.vmw”
深入理解Handler
Handler应该是Android开发过程中使用最频繁的类了,但你真的理解Handler了吗?本文深入剖析Handler内部的实现机制,以及分析使用过程中常出现的内存泄漏的问题。本文针对使用过Handler的用户,没有再介绍Handler的使用。Handler的用途与Handler的相识相知,一般是通过子线程更新UI的Exception创造的机会。android.view.ViewRootImpl$CalledFromWrongThreadException:Onlytheoriginalthreadthatcreatedaviewhierarchycantouchitsviews.Handler可以用于切换到主线程更新UI,但是它的作用绝不仅于此。源码中Handler类的注释说的很简单、明确。摘录如下,翻译水平有限:AHandlerallowsyoutosendandprocessMessageandRunnableobjectsassociatedwithathread
否定应答(NACK)
这篇文章翻译自:http://www.rabbitmq.com/nack.html消费者在AMQP0-9-1中可以选择对投递使用手动ACK。AMQP0-9-1规范定义了basic.reject方法,使客户端可以拒绝单个已投递的消息,以及指示代理移除他们或者重新入队列。不幸的是,basic.reject没有提供对大批量消息否定应答的支持。为了解决这个问题,RabbitMQ支持basic.nack方法,除了提供basic.reject的所有功能,还支持大批量消息的处理。为了以批量方式拒绝消息,客户端设置basic.nack方法的多个标识为true。然后代理将拒绝所有未确认已投递的消息,直至并包括basic.nack方法中delivery_tag字段指定的消息。在这个方面,basic.nack完成了basic.ack的批量ACK语义。这个例子拒绝单个消息,并请求代理将它重新入队列:GetResponsegr=channel.basicGet("some.queue",false);ch
Apache RocketMQ 顶级项目之路
序言2016年11月,阿里将RocketMQ捐献给Apache软件基金会,正式成为孵化项目。至此,RocketMQ开启了迈向全球顶级开源软件的新征程。通过社区半年多的努力。9月25日,Apache软件基金会官方宣布,阿里巴巴捐赠给Apache社区的开源项目RocketMQ从Apache社区正式毕业,成为Apache顶级项目(TLP)。在通向Apache顶级项目的这些时间里,团队走了很多路,也经历了很多事。第一次按照ApacheWay走通Apache软件发布流程,完成了在整个IPMC都极为罕见的Rc3发布壮举,体现了中国团队的严谨、高效,赢得了社区的赞誉。第一次吸纳外籍Committer-日本博士Roman。2个月时间里,他提交近20个PullRequest,推动RocketMQ跟Apache其它顶级社区项目合作,对社区起步做出了卓越贡献。第一次面向社区举办编程马拉松。PMC成员全程跟进,帮助参赛选手评审设计、Review代码。第一次吸纳PMC成员。在RocketMQ社区,PMC是对Committer持续贡
[原]延时任务队列
本文方案是看了58的一位架构师的分享,但并没有实现细节。本文是对方案的深入研究及代码实现业务场景1.下单之后如果三十分钟之内或12小时没有付款就自动取消订单2.下单成功后60s之后给用户发送短信通知3.用户希望通过手机远程遥控家里的智能设备在指定的时间进行工作。这时候就可以将用户指令发送到延时队列,当指令设定的时间到了再将指令推送到只能设备。4.七天自动收货5.一定时间后自动评价6.业务执行失败之后隔10分钟重试一次…….本质都是过一段时间后才执行任务下单成功后60s之后给用户发送短信通知为例。实现:启动一个定时任务,每分钟查一次数据库表,把下单成功超过60秒并且没有发过短信通知的的取出来,然后去处理。缺点:1.如果数据量很大,查表轮询效率就低。2.每分钟轮询一次增加了数据库压力。3.如果是增大轮询时间间隔,那么时效性(准确性)又降低了方案二:redis实现:通过zset机构模拟,定时器去读zset数据去处理。不足:1.数据量大,一zset性能有问题。