关于中间件:上海得物技术沙龙中间件专场火热报名中

本次中间件专场沙龙由得物技术出品,聚焦于行业最新的技术趋势和实际,将在上海(线上同步直播)为你带来四个令人期待的演讲话题:《得物蓝绿公布演进和落地》《基于istio的Service Mesh落地实际 》《Apache Pulsar -- 金融级云原生音讯平台》《得物DLB演进之路》。置信这些话题将对你的工作和学习有所帮忙,咱们期待着与你独特探讨这些令人兴奋的技术内容! 流动工夫:2023年8月27日 14:00 ——18:00(13:30开始签到)流动地点:上海市杨浦区黄兴路221号互联宝地C2栋5楼 培训教室地铁中转:地铁12号线宁国路-1号口出报名形式:点击报名 中间件技术沙龙 报名胜利后可在「得物技术」公众号后盾回复「小助手」,增加小助手微信,退出沙龙群交换互动、获取沙龙会场路线指引|直播地址|课后材料 议程介绍13:30-14:00 签到、支付伴手礼、拍照打卡14:00-14:10 主办方收场/得物CTO致辞/出品人介绍14:10-14:50 《得物蓝绿公布演进和落地》-- 得物 对立框架&散布式调度负责人 宋加林14:50-15:30 《基于istio的Service Mesh落地实际》-- 信也科技 资深架构师 徐玉强15:30-15:50 茶歇15:50-16:30 《Apache Pulsar -- 金融级云原生音讯平台》-- Apache Member,Apache Pulsar PMC 成员,StreamNative 联结创始人 翟佳16:30-17:10 《得物DLB演进之路》-- 得物 中间件技术专家 陈浩17:10-17:30 现场合影、支付互动礼品留神:场地无限,入场伴手礼仅限前50名到场同学 话题简介《得物蓝绿公布演进和落地》得物对立框架&散布式调度负责人-宋加林随同着业务的持续增长,企业微服务的规模也会日益宏大。如何高效的实现微服务版本的无缝更新与切换是一个微小挑战。蓝绿公布便是其中一种解决方案,通过部署两个独立的生产环境,实现无缝更新和回滚,确保用户体验的连续性。 本次分享将具体介绍蓝绿公布的原理和收益,深入探讨如何创立和治理两个环境,如何进行流量比例控制、流量粘性管制。通过蓝绿公布,能够升高危险,放慢公布速度,并实现继续交付。当然,蓝绿公布的落地并不是一帆风顺的,在分享中,还将探讨实际中可能遇到的挑战,并提供解决方案。 《基于istio的Service Mesh落地实际》 信也科技资深架构师-徐玉强近几年云原生技术⻜速倒退,Service Mesh被称为下一代的微服务,或间接称之 为微服务2.0。istio作为其中佼佼者,俨然成为Service Mesh的事实标准。isito应用对立 的边⻋实现了异构语言和框架的治理对立,提供了流量治理、可观测性、平安等能力, 克服了传统微服务治理中的降级之殇。 本次分享会展现如何从传统微服务迁徙到istio体系,istio落地带来了哪些业务价值,以及istio的推广过程中的“踩坑”记录。 《Apache Pulsar -- 金融级云原生音讯平台》 Apache Member,Apache Pulsar PMC成员,StreamNative联结创始人-翟佳Apache Pulsar是开源的下一代的Pub/Sub音讯零碎,Pulsar通过特地的设计和形象,对立地反对Streaming和Queueing两种音讯生产模式,放弃了Streaming模式的高性能和Queueing模式的灵活性,在金融场景中经验了大规模压力的测验。 Pulsar在保障大数据音讯零碎的性能和吞吐量的同时,提供了更多企业级的Feature,包含不便的运维和扩大,灵便的音讯模型,多语言API,多租户,异地多备,和强持久性一致性等等,解决了现有开源音讯零碎的一些有余。 比方, Pulsar对音讯零碎中比拟难解决的强一致性和持久性问题给出了比拟优雅的解决形式;Pulsar通过基于Segment的存储架构,很容易地化解了其余音讯零碎中的扩大和运维的难题。 《得物DLB演进之路》 得物中间件技术专家-陈浩DLB是一个七层负载组件,承载着得物全站的流量接入,作为入口层,负责南北向流量的散发的工作,负担着在高流量高并发下稳固运行的外围压力;DLB基于openResty构建,在此之上深度交融改良了Nginx的多项性能和指标,解决了一些业界前沿性的的难题,如无reload下的配置更新能力和流量镜像;此外也在云原生和混合语言开发域进行积极探索。 购票须知1.报名形式:点击报名 中间件技术沙龙2.报名须知:凭【邀约短信】验票签到入场如果购票有疑难,请分割主办方:18301920753 ...

August 16, 2023 · 1 min · jiezi

关于中间件:进阶篇丨链路追踪Tracing很简单链路成本指南

狭义上的链路老本,既蕴含应用链路追踪产生的数据生成、采集、计算、存储、查问等额定资源开销,也蕴含链路零碎接入、变更、保护、合作等人力运维老本。为了便于了解,本大节将聚焦在广义上的链路追踪机器资源老本,人力老本将在下一大节(效率)进行介绍。 链路追踪机器老本的组成构造链路追踪机器老本次要分为客户端和服务端两大类。链路追踪客户端(SDK/Agent)通常运行在业务过程外部,与业务程序共享 CPU、内存、网络、磁盘等系统资源。链路追踪的客户端开销次要包含链路埋点拦挡、链路数据生成与透传、简略的预聚合或压缩/编码等数据处理、数据缓存与上报等。客户端开销通常属于一种隐性开销,短期内不会间接导致资源账单的增长,而是利用业务过程闲置局部的资源。然而,当业务持续增长或者进入峰值周期(如大促),链路追踪耗费的这部分资源最终会引发理论账单的增长。因而,这部分的开销要严格控制在一个正当的水位之内,比方不超过 10%,否则会显著影响业务的失常运行。 链路追踪的服务端机器老本是一种显性的、即时投入的资源老本,也是在评估链路追踪选型计划时(自建、托管)的重要考量因素。链路追踪的服务端通常由网关、音讯缓冲、流计算、存储与查问端组成,最为人们所熟知与关注的是链路存储模块,许多热点文章探讨的链路尾部采样(Tail-based Sampling)次要影响的就是链路追踪服务端存储老本。然而,在短周期存储(如 3~7 天)场景下,链路数据接管、缓冲与解决的资源老本占比甚至会超过存储,也是不容忽视的重要组成部分。 此外,还有一块容易疏忽的老本就是客户端与服务端之间的网络传输费用。特地是在跨公网传输场景下,岂但带宽老本高,而且传输流量会受限,常常须要开启头部采样(Head-based Sampling)来升高链路数据上报量。 近年来,支流开源社区或商业化产品陆续推出了边缘集群解决方案,即在用户网络(VPC)下,部署一套可观测数据对立采集与解决集群,反对多源异构数据标准化、链路数据无损统计、错慢全采等个性,能够进一步升高链路数据上报与长久化存储老本。整体架构如下图所示。 链路追踪机器老本优化清晰了链路追踪机器老本的组成构造,咱们接下来剖析如何进行针对性优化。在这里,先提出三个问题:“每一条链路数据的价值都相等吗?”、“对链路数据的加工解决是越早越好,还是越晚越好?”、“链路数据的存储时长是越久越好,还是越短越好?”。 为了解答上述疑难,咱们要搞清楚链路数据的用法和价值到底是什么?链路数据次要有三种用法,一是依据特定条件筛选并查问单条调用链明细轨迹,用于具体问题的诊断与定位;二是基于固定的维度进行链路预聚合,提供服务接口等通用粒度的监控与告警;三是基于链路明细进行自定义后聚合,满足个性化的链路剖析需要,如 VIP 客户大于 3S 的慢申请接口散布。 因而,蕴含不同特色的链路数据价值并不相等,错慢链路或含有特定业务特色的链路(统称为要害链路),往往比一般链路的价值更高,被查问的概率更大。咱们应该记录更多的要害链路,并进步其存储时长;一般链路应该更少记录,并升高存储时长。此外,为了保障统计数据的精确度,咱们应该尽早实现链路数据的预聚合,这样就能够更早的进行链路采样,升高明细数据的整体上报与存储老本。 综上所述,咱们能够从“链路歪斜采样”、“链路计算左移”、“冷热存储拆散”等方面进行摸索,尝试以最低的老本,按需记录最有价值的链路数据,实现老本与体验的动态平衡与优化,如下图所示。 链路歪斜采样,记录更有价值的数据链路数据的价值散布是不平均的。据不齐全统计,调用链的理论查问率通常小于百万分之一,也就是说,每一百万条调用链,只会有一条被理论查问命中,其余链路简直都是有效存储。全量存储调用链不仅会造成微小的老本节约,也会显著影响整条数据链路的性能及稳定性。因而,链路采样(Trace Samplling)的理念随之诞生。 早在 Google Dapper 论文问世的时候,就提出了基于固定比例进行链路采样的办法,并在 Google 外部生产零碎失去了实际测验。比方每 1024 条链路采样记录其中一条,采样比例为 1/1024。然而,固定比例采样仅仅解决了管制链路开销的问题,而漠视了链路价值散布的不平均性,要害链路与一般链路被采样的概率都是雷同的,这就导致许多针对要害链路的查问后果呈现未命中,极大影响了问题排查的效率。 那么,咱们是否提前预测用户行为,只记录会被查问的链路呢?100% 精准预测十分艰难,简直难以实现,然而依据历史行为和畛域教训进行揣测,优先记录查问概率更大的链路是比拟可行的一种降本计划,这就是链路歪斜采样。 链路歪斜采样通常是针对特定的链路特色(如错、慢、外围接口或自定义业务特色)设置较高的采样比例(如 100%)或流量阈值(如前 N 条/分钟),不合乎要害特色的链路以极低的比例采样(如 1%)甚至不采样。如下图所示的阿里云链路追踪自定义采样配置页面,用户能够依据本身须要自在定制特色采样策略,在保障较高的查问命中率(如 50%+)的前提下,链路数据理论存储量能够达到原始数据量的 5% 左右,极大的节俭了服务端长久化存储的老本。更多链路采样策略将在实战篇进行具体介绍,比方动静采样。 延长一下思路,咱们在做问题诊断时,除了调用链之外,通常还须要联合日志、异样堆栈、本地办法耗时、内存快照等关联信息进行综合判断。如果每一次申请的关联信息全都记录下来,大概率会造成零碎的解体。因而,借鉴“链路歪斜采样”的理念,抛弃无用或低价值数据,保留异样现场或满足特定条件的高价值数据,精细化的按需存储能力应该成为掂量 Tracing 乃至可观测产品优劣的重要规范之一。如下图所示,阿里云 ARMS 产品提供了慢调用场景下主动保留残缺本地办法栈的能力,能够实现慢调用的行级代码定位。 链路计算左移,提炼数据价值除了筛选记录更有价值的数据之外,还能够将数据加工计算从服务端“左移”至客户端或边缘集群,提前完成数据价值提炼,如预聚合或压缩编码,这样就能够在满足用户查问需要的前提下,无效节俭数据传输与存储老本。 预聚合统计:在客户端进行预聚合的最大益处, 就是在不损失数据精度的同时大幅缩小数据上报量。比方,对调用链进行 1% 采样后,依然能够提供精准的服务概览/上下游等监控告警能力。数据压缩:对反复呈现的长文本(如异样堆栈,SQL 语句)进行压缩编码,也能够无效升高网络开销。联合非关键字段模糊化解决成果更佳。冷热存储拆散,低成本满足个性化剖析需要链路采样和计算左移的思路都是尽可能减少链路明细数据的上报与存储,从而达到降老本的目标。这两种做法能够比拟好的满足单链路查问与通用场景下的预聚合监控告警,但却无奈满足多样化的后聚合剖析需要,比方某个业务须要统计耗时大于 3 秒的接口及起源散布,这种个性化的后聚合剖析规定是无奈穷举的。而当咱们无奈事后定义剖析规定时,貌似就只能采纳老本极高的全量原始数据存储。难道就没有优化的空间么?答案也是有的,接下来咱们就介绍一种低成本解决后聚合剖析问题的计划——冷热存储拆散。 冷热存储拆散的根底在于用户的查问行为满足工夫上的局部性原理。简略了解就是,工夫越近的热数据查问概率越大,工夫越久的冷数据查问概率越小。例如,因为问题诊断的时效性,50% 以上的链路查问剖析产生在 30 分钟内,7 天之后的链路查问通常集中在错慢调用链。实践根底成立,接下来探讨如何实现冷热存储拆散。 首先,热数据存在时效性,如果只需记录最近一段时间内的热数据,对于存储空间的要求就会降落很多。另外,在私有云环境下,不同用户的数据人造具备隔离性。因而,在用户 VPC 外部的热数据计算和存储计划就具备更优的性价比。 其次,冷数据的查问具备指向性,能够通过不同的采样策略筛选出满足诊断需要的冷数据进行长久化存储。例如错慢采样,特定业务场景采样等。因为冷数据存储周期较长,对稳定性要求较高,能够思考在共享数据中心对立治理。 综上所述,热数据存储周期短,成本低,但能够满足实时全量后聚合剖析需要;而冷数据通过精准采样后数据总量大幅降落,通常只有原始数据量的 1% ~10%,并能够满足大多数场景的诊断诉求。两相结合,实现了老本与体验的均衡最优解。国内外当先的 APM 产品,如 ARMS、Datadog、Lightstep 均采纳了冷热数据拆散的存储计划。 ...

June 1, 2023 · 1 min · jiezi

关于中间件:vivo-超大规模消息中间件实践之路

作者:vivo 互联网存储技术团队-Luo Mingbo、中间件团队- Liu Runyun 本文依据“2022 vivo开发者大会"现场演讲内容整顿而成。 本文次要介绍超大数据规模场景下分布式消息中间件在vivo的利用实际。 在线业务侧次要从RocketMQ集群部署架构、平台零碎架构、日常运维操作平台、监控告警一体化实际以及vivo如何通过建设AMQP音讯网关的形式实现所有在线业务服务从RabbitMQ到RocketMQ的业务无感迁徙,实现了在线业务消息中间件组件的对立。 大数据侧次要从资源隔离、流量平衡、智能动静限流、集群治理四个维度介绍Kafka在vivo的最佳实际以及Kafka核心技术架构在超大数据规模场景下的缺点以及将来对Pulsar组件的长线布局和建设。 一、分布式消息中间件在vivo的经营现状1.1 技术选型 在技术选型上,咱们从吞吐量、性能个性、生态集成、开源沉闷等多个维度比照了以后支流的分布式消息中间件,最终在线业务侧咱们抉择基于RocketMQ构建音讯平台,依靠RocketMQ丰盛的性能个性满足业务间削峰、解耦、异步化的需要。 大数据侧咱们抉择具备高并发、高可用、低提早、高吞吐能力的分布式消息中间件Kafka。构建超大数据规模解决能力的对立数据接入服务和实时数仓服务。Kafka组件作为对立数据接入服务,是大数据全链路中的咽喉要道,是大数据生态体系建设中不可或缺的重要组件之一。 1.2 规模现状经营指标方面目前大数据业务侧Kafka集群接入我的项目数百、接入规模方面Topic数量达到数万、集群日均解决音讯达数十万亿条、可用性保障99.99%、单机日均解决音讯达数百亿条。 在线业务侧RocketMQ集群接入我的项目数百、接入规模方面接入数千服务、集群日均解决音讯达数百亿条、可用性保障100%,发送均匀耗时<1ms。 二、大数据侧消息中间件最佳实际2.1 Kafka简介 首先咱们看下Kafka的官网定义及倒退历史,Kafka是由Apache软件基金会开源的一个流解决平台,是一种高吞吐量的分布式公布订阅音讯零碎。具备高吞吐、低提早、高并发、高可用、高可扩等个性。 Kafka是由LinkedIn公司在2010年开源,2011年交由Apache软件基金会进行孵化,2012年成为Apache软件基金会的顶级开源我的项目。 2.2 Kafka在超大数据规模场景下面临的挑战 在超大数据规模场景下咱们会面临以下几个问题? 如何布局资源隔离保障外围业务、高优业务、个别业务之间互相不受影响?如何保障集群外部节点间流量平衡,升高单节点或局部节点流量差别太大带来的资源节约?超大数据规模场景下如何进行限流保障集群的稳定性并尽可能升高对业务可用性的影响?集群长期运行,客户端版本多样,如何继续保障集群的高可用性?上面我将从资源隔离、流量平衡、智能动静限流、集群治理四个维度和大家一起交换Kafka在vivo的最佳实际。 2.3 资源隔离 资源隔离的核心作用在于防止业务与业务之间的相互影响,但隔离粒度、资源利用率、运维老本之间如何进行衡量,是咱们须要思考的重点。隔离粒度太粗会导致隔离成果不佳,隔离粒度太细会导致资源利用率较低、运维成本增加。 那vivo在Kafka集群资源隔离上是如何均衡三者关系的呢? 首先咱们依据业务属性、业务线两个维度进行集群维度的隔离,例如咱们在集群划分上分为了商业化专用集群,监控专用集群,日志专用集群等。在集群维度做了机器资源的物理隔离。 同时咱们在集群外部引入了资源组的概念。同一个集群外部能够蕴含多个资源组。每个资源组能够为多个业务提供服务。资源组与资源组之间互相独立。 上图中右上图是咱们没有引入资源组概念时集群外部不同业务Topic分区的扩散状况,大家能够看到业务A和业务B的Topic分区扩散到集群内的所有broker上,若业务A的流量突增可能会造成业务B受到影响,右下图是咱们引入资源组概念后不同业务Topic分区的扩散状况,能够看到不同业务的topic分区只会调配到本人业务所属的资源组内,即便业务A的流量突增导致机器不可用也不会对业务B造成影响。 引入资源组概念后让咱们能在集群外部实现机器资源的逻辑隔离。所以咱们在资源隔离方面采纳了物理隔离和逻辑隔离两种形式相结合,实现了在超大数据规模场景下Kafka集群的资源隔离计划。 2.4 流量平衡 流量平衡的核心作用在于充分利用集群外部资源,晋升资源利用率。Kafka服务作为一个有状态的服务,Kafka在技术架构设计上Topic分区与节点绑定,不反对分区同一正本数据在磁盘和节点维度扩散存储。对分区的读写申请都由分区Leader所在节点进行解决。所以Kafka集群流量平衡的实质是Topic分区的扩散平衡。 在流量平衡方面咱们做两期的建设,第一期咱们在分区扩散平衡算法上引入机器的实时出入流量、cpu负载、磁盘存储等指标作为负载因子生成分区迁徙打算。执行分区迁徙后达到流量平衡的目标。流量平衡一期性能上线后咱们将资源组内节点间流量差别从数百兆/s升高到数十兆/s。随着集群数据规模的继续减少,咱们发现数十兆/s的流量差别仍然会造成资源节约。 所以在流量平衡二期性能建设上咱们减少了分区扩散平衡、Leader扩散平衡、正本扩散平衡、磁盘平衡等Kafka元数据指标作为负载因子生成Kafka分区迁徙打算,并在分区迁徙执行上减少了多种迁徙提交策略。流量平衡二期性能上线后咱们将资源组内节点间流量差别从数十兆/s升高到十兆以内/s。 上图是咱们流量平衡一期性能上线前后资源组内节点的流量监控面板,能够看到一期性能上线前资源组内节点间的流量偏差在数百兆/s。一期性能上线后资源组内节点间流量偏差在数十兆/s以内,资源组内节点间流量偏差升高75%。极大晋升了服务端的资源利用率。 上图是咱们流量平衡二期性能上线前后资源组内节点的入出流量监控面板,能够看到节点间入出流量偏差从数十兆/s升高到十兆以内/s,资源组内节点间流量偏差升高80%。成果也是非常明显。 2.5 智能动静限流 限流的实质是限度客户端的流量突增以确保服务端的可用性。防止客户端的流量突增导致服务端整体不可用。限流的粒度,限流阈值的设定,资源利用率、服务端稳定性之间应该如何做衡量呢?是咱们须要思考的重点。限流粒度太粗会导致限流成果不佳,当大部分业务同时流量突增会对服务端的稳定性带来危险。限流粒度太细服务端应答客服端流量突增能力有余,限流阈值设置太大会给服务端稳定性带来危险,限流阈值设置太小会导致服务端资源利用率较低。 限流方面, 首先咱们采纳多平台联结诊断机制依据我的项目理论生产数据状况判断是否须要进行流量调整,计算调整后的限流阈值。其中多平台蕴含(JMX对立指标采集平台,对立监控平台、对立告警平台、Kafka集群治理平台等)。第二、智能剖析Kafka集群服务资源负载状况,计算各资源残余状况。确定是否能够进行阈值调整并联合客户端理论生产数据状况计算阈值调整到多少适合。第三、主动实时调整限流阈值。通过以上三步实现智能动静限流计划。解决了限流粒度、限流阈值设定、资源利用率、Kafka集群可用性四者之间的均衡关系。 实现智能动静限流后给咱们带来以下几点显著的收益。 大大晋升Kafka集群服务端应答客户端流量突增的能力。利用我的项目错峰的形式进一步晋升Kafka集群的资源利用率。智能化主动调整我的项目限流阈值无需人工染指,大大降低Kafka集群在超大数据规模场景下的运维老本。动静依据服务端负载状况调整我的项目限流阈值,尽可能减小限流对业务可用性的影响。2.6 集群治理 Kafka集群元数据对立由ZooKeeper集群治理,元数据信息永恒无效永不过期,元数据的下发由Kafka Controller节点对立下发,随着业务的一直倒退,数据规模的一直减少,集群外部Topic的数量达到万级,分区数量达到数十万级。元数据治理能无效防止元数规模给Kafka集群稳定性带来的影响。随着接入的服务、Kafka用户越来越多,正确的应用Kafka 客户端也能大大晋升Kafka服务端的稳定性和资源利用率。Kafka分区与磁盘目录绑定,创立Topic、Topic分区扩容时依据Topic流量正当设置Topic分区数能无效防止单机或单盘性能瓶颈成为集群整体的性能瓶颈。 vivo在Kafka集群治理方面实现了节点流量偏差治理、Topic元数据治理、Topic分区数据歪斜治理、Topic超大分区治理、Topic生产提早治理等计划为Kafka集群的高可用性保驾护航。 2.7 实践经验积淀 vivo Kafka消息中间件团队在三年工夫内,依据理论的业务场景和生产数据规模积淀了较多的实践经验。例如在高可用/高可扩方面实现了机架感知、弹性伸缩、数据压缩等能力建设,在监控告警方面提供了用户限流告警、Topic流量突增告警、生产提早告警、Leader实时监控告警,多平台联结故障感知告警等能力建设。咱们为Kafka集群做了很多的扩大能力建设,那解决了Kafka集群在超大数据规模场景下的所有问题了吗?答案是否定的。 接下来咱们一起看看Kafka集群在超大数据规模场景下面临的新挑战。 2.8 Kafka在超大数据规模场景下由技术架构带来的缺点 由Kafka架构设计所带来的一些痛点无奈通过扩大能力解决,并且Kafka架构设计上分区同一正本数据与磁盘强绑定不反对扩散存储、不反对存储与运算拆散、不反对冷热数据分层存储等设计缺点在超大数据规模场景下显得尤为显著。所以在超大数据规模场景下Kafka集群面临了以下几个痛点。 资源利用率低。无奈疾速响应业务增长。故障复原工夫长。历史数据生产故障率高(次要体现在磁盘io性能上)。2.9 大数据侧分布式消息中间件将来布局基于以上Kafka在架构设计上的缺点,vivo Kafka团队于2021年开始对另一款开源分布式消息中间件Pulsar进行调研。 2.9.1 Pulsar简介 咱们看下Pulsar的官网定义及发展史:Pulsar 是 Apache软件基金会的顶级开源我的项目,是集音讯、存储、轻量化函数式计算为一体的下一代云原生分布式音讯流组件,采纳了计算与存储拆散的架构设计,反对多租户、长久化存储、多机房跨区域数据复制,具备高并发、高吞吐、低延时、高可扩,高可用等个性。 ...

January 30, 2023 · 1 min · jiezi

关于中间件:支撑阿里双十一的消息中间件带你云淡风轻面对高并发

近几年来,“中台”一词频繁呈现在公众视线中,技术中台、业务中台、数据中台、甚至AI中台……层出不穷。 这体现了整个行业对构建可复用体系的高度期待,心愿依靠中台策略来解决企业外部大量构建烟囱式零碎所带来的一系列问题:反复建设、数据孤岛、资源利用率低等。 阿里巴巴开源的一款高性能、高吞吐量、低提早的消息中间件——RocketMQ,是从实际中走进去的。它采纳 Java 作为开发语言,推出的泛滥高级个性并不是技术者的自娱自乐,而是来源于对业务场景的深度打磨,受到了宽广互联网架构师的青眼,曾经成为互联网行业首选的消息中间件之一。 多年以来,RocketMQ 承载了阿里巴巴“双十一”的大部分业务,能够说是一名久经沙场的“精英”、值得信赖的“搭档”。因为消息中间件通常承载着最外围的业务,所以一旦使用不当,就很容易造成重大故障。因而,了解 RocketMQ 外围原理与把握其最佳实际成了开发人员与运维人员的必备技能。 新书《RocketMQ实战》由RocketMQ首席布道师联结中间件实战专家联结打造,有了它,线上环境呈现零碎忙碌的时候,你就能更加熟能生巧地解决问题,而不是慌手慌脚地到处查找材料啦~~ 内 容 简 介《RocketMQ实战》旨在让每一位RocketMQ 初学者通过对本书的学习,疾速“打怪降级”,成为RocketMQ 畛域的佼佼者。本书从应用场景动手,介绍如何应用RocketMQ,应用过程中会遇到什么问题,如何解决这些问题,以及为什么能够这样解决。还包含运维监控治理,配以故障案例剖析,笼罩了 RocketMQ 整个生命周期。更有源码级别论述,可能从中领会 RocketMQ 的各种设计思维,在实战中吃透RocketMQ 外围原理。 特 色 整 理RocketMQ首席布道师联结中间件实战专家匠心打造用超过官网文档的实际细节带你短时间内疾速上手 RocketMQ更有源码级论述领会 RocketMQ 的设计思维 本 书 适 合 谁软件开发、测试人员:助你相熟外围原理,把握最佳实际,避开应用中的可能碰到的坑。RocketMQ 运维人员:助你构建运维治理体系,保障生产环境RocketMQ集群安稳衰弱运行。 所有想要理解 RocketMQ的开发者,本书也可作为培训教材。 作 者 简 介丁威,《RocketMQ 技术底细》联结作者,RocketMQ 官网社区首席布道师、Qcon 研习社讲师、RocketMQ 寰球开发者峰会讲师,热衷于中间件畛域的技术分享,保护“中间件趣味圈”公众号,陆续发表 350+篇原创文章。 目前负责中通快递技术平台部资深架构师,次要负责全链路压测、消息中间件、数据同步等产品的研发与落地,领有千亿级音讯集群的运维教训。 梁勇,《RocketMQ 技术底细》审稿人、ArchSummit 寰球架构师峰会讲师、QCon研习社讲师、极客工夫训练营中间件专题讲师。 深耕中间件畛域多年,从事中间件相干的开发和治理工作。在公众号 “瓜农老梁”继续发表中间件相干文章,涵盖开源中间件的源代码剖析、实战笔记、性能优化、方案设计等。参加和主导了自建 IDC 数据中心、异地多活、流量泳道染色、全链路压测、混沌工程等泛滥计划的设计与落地。 RocketMQ 诞生于互联网,经验了超大规模互联网业务的锻炼和洗礼,又在阿里云上实现了云原生的变质与降级,曾经倒退为国内十分受欢迎的开源软件。 这本《RocketMQ实战》分明地介绍了 RocketMQ 在音讯存储上的设计要害,能够让技术人员在选型消息中间件的时候更好地比照优劣,做出最正当的决策,同时本书深入浅出地介绍了许多实践经验,能够帮忙工程师解决理论问题。强烈建议 RocketMQ 的关注者人手一本! 快来通过本书摸索 RocketMQ 的技术魅力吧!

October 12, 2022 · 1 min · jiezi

关于中间件:在线数据迁移数字化时代的必修课京东云数据迁移实践

突破数据边界,是数字化时代常挂在嘴边的一句话,数据的价值是在流动中体现的,数据利用也是如此。以往为了满足开发、测试、数据保护容灾和数据分析的须要,咱们一直对数据进行复制、备份、迁徙,因而数据迁徙十分重要。 混合多云时代,用户数据迁徙需要与场景激增 明天咱们来重点聊聊混合云时代中数据迁徙,先来看看常见的几种企业数据迁徙的需要与场景: 传统云化型:设施老旧,须要降级,硬件老本降级性价比不高,云上更经济; 价格敏感型:综合比照多家厂商价格,灵便选型采纳老本最优计划; 灾备驱动型:须要多云、异构云来架构本人的灾备体系,保证数据的平安 游戏客户:异地开服,服务不同地区的用户,因各地网络品质不统一须要多云模式用于构建服务本地用户的游戏服务器。 泛金融客户:要合乎金融平安政策的要求,须要数据的迁徙 这些客户都因零碎和技术升级、业务的倒退、以及平安合规等因素采纳混合多云的计划,同时对其数据的迁徙有着很高的诉求,在不同的业务模式和需要下也会面临多种问题。 混合多云时代下,数据迁徙的窘境 数据库的倒退多样性晋升迁徙门槛 混合多云时代,迁徙是面临的一大难题,其中数据安全迁徙往往又是企业最关注的。提到数据迁徙的艰难,究其原因先粗略回顾下关系型数据库到非关系型数据库的倒退。 关系型数据库,是指采纳了关系模型来组织数据的数据库。关系模型是在1970年由IBM的研究员E.F.Codd博士首先提出的,在之后的几十年中,关系模型的概念失去了充沛的倒退并逐步成为支流。关系型数据库具备事务一致性、读写实时性、结构化与规范化等个性,因此容易了解、使用方便、易于保护,在虚机时代,互联网还未遍及时它是最支流的数据库,典型的代表有Oracle、Microsoft SQL Server、DB2、MySQL等。 但随着互联网的飞速发展,网站用户并发高,海量数据的产生,传统关系型数据库曾经不能满足企业的数据存储需要了,非关系型数据库应势而生,它高并发,读写能力强、弱化数据结构一致性,应用更加灵便有良好的可扩展性等劣势逐步成为了企业的首选。 NoSQL一词首先是Carlo Strozzi在1998年提出来的。典型代表Redis, Amazon DynamoDB, Memcached,Microsoft Azure Cosmos DB等 在面对这两种数据库之间的迁徙,关系型数据库SQL RDBMS倒退久,迁徙生态工具齐全,且大部分数据库产品都自带迁徙工具;而非关系NoSQL,数据定义更宽松,产品体积轻量,放弃了一致性校验,导致某些数据结构滥用,晋升了迁徙难度。而迁徙工具大部分凋谢给生态来做,因为倒退工夫较短,工具欠缺度不如RDBMS高。 厂商试图“数据绑架”,使迁徙雪上加霜 剖析完关系型数据库到非关系数据库的倒退,能够看到数据存储构造自身已产生了微小的变动,这从根因上已大幅晋升了迁徙的难度,而一些云厂商对数据库的再次革新,且对关系型数据库底层革新不通明,导致数据库的复杂性大大加大,试图用数据迁徙老本高来长期绑定客户,更是令数据的迁徙雪上加霜。 “个体差异”导致通用型解决方案缺失 不同的企业因为本身需要不同与应用场景的多样性,每一个客户,对咱们来说都是一个新的案例,咱们必须“量身定制”化服务,但在过程中咱们也总结出几类常见难点: 难点一:多节点数据库迁徙,节点数量不统一 难点二:原生产品跨版本问题,版本不统一且高低版本兼容性不够好 难点三:缓存类数据易失性更高 面临挑战,京东云破局迁徙窘境 上面通过理论案例和大家分享咱们是如何破局迁徙窘境,帮忙用户解脱数据桎梏的。 重大挑战,临危不乱/慌慌张张 2019年京东物流为了实现其轻资产化、降低成本、降级架构的三大目标,将其ES开始由本地机房迁徙到云上。依靠京东云云搜寻ES高可用、易扩大、近实时等个性,京东物流胜利地将分拣核心自动化零碎、冷链流程监控零碎、凋谢订单跟踪零碎等上百个零碎迁徙上云。 在迁徙过程中京东云不仅提供了惯例的停机迁徙计划,还提供了非凡的不停机迁徙计划,保障了物流业务不停服。不停机迁徙计划如下:在云端创立新集群,将云上集群和用户集群合并成一个大集群,利用Elasticsearch数据分布API(cluster.routing.allocation.exclude)将用户集群中的索引数据迁徙到云上集群的数据节点,最初将用户集群和云上集群形成的大集群拆分,敞开用户集群即可实现迁徙。(采纳这种形式须留神同时满足以下两个条件:用户集群版本和云上集群版本雷同;用户集群所有节点和云上集群所有节点网络可能互通。) 通过上述办法,很快就就实现了京东物流近百个零碎的数百个集群、数千个节点数据上云工作。在此之上京东云还配套提供了一键报警等外围性能,对上云工作进行全天候、全方位的保障。 截止目前,京东物流已有超过90%的利用在私有云上部署了实例,去年11.11期间业务量超过日常三倍以上的状况下,整体经营安稳。 迁徙利器,上云必备 关系型数据库仍然是各行业的支流利用之一,怎么更快的将传统关系型数据中的数据迁徙上云也是很多行业用户关怀的。为此京东云特意打造了一款针对关系型数据库的迁徙工具——数据传输DTS。 数据传输DTS 提供实时数据流服务,反对数据迁徙、数据订阅和数据同步服务,可简略不便的满足数据上云、业务异步解耦、数据异地灾备、业务零碎数据流转等业务场景。目前数据传输DTS反对MySQL、MariaDB、Percona、SQL Server、PostgreSQL等多种数据库迁徙,能够简略疾速地将本地自建数据库迁徙至京东云,源数据库在迁徙过程中可持续失常运行,从而最大水平地缩小应用程序的停机工夫。 一直冲破,技术创新 某家在线广告公司须要将Redis从自有机房迁徙到云上。因为客户零碎承载着大量结算缓存和业务缓存所以要求在迁徙过程中不能有业务中断。过后有一些开源工具,然而不满足要求。次要是因为版本问题,客户用的Redis版本是4.0而过后开源的工具只反对3.28及以下版本。本着京东客户业务为先的准则,和激励翻新的技术精力,咱们思考,能不能为客户自研一套工具,可能Cover住Redis数据流转大部分场景的通用工具,于是2019年7月redissyncer 1.0版本诞生,实现了数据源及指标校验、原生集群同步、 大KV的拆解等基本功能。 1.0完后很快迎来了几个客户: 其一是互联网行业用户,Redis单实例,数据体量不大20Gb左右。咱们通过启动参数修复、调整每批次Value值等细节优化顺利完成了迁徙工作; 第二个用户是游戏行业的用户,用户须要将自有IDC中的Redis迁徙到京东云。在应用咱们的产品之前,用户本人找过若干开源产品但都不符合要求。因为用户的实例数量较多,在理解过Redissyncer产品个性后,用户决定应用咱们的工具自行迁徙。 贴近一线,无所不至 通过一个下午的培训近程培训,用户很快上手第一个实例迁徙很顺利。在接下来的几天用户通过咱们的工具陆续实现迁徙工作,并反馈中给予产品很高评估,并特意发来感谢信。 来自客户的认可,是咱们一直向前的最大能源! 一直打磨,精益求精 在分析过更多客户痛点与需要后, 2019年11月底,咱们实现了2.0版本的降级,补充了同步模式拆分、断点续传、离线文件加载、跨版本迁徙、流式加载等性能。 很快2019年12月咱们又迎来了一个金融用户。用户须要将原生Redis集群迁徙到自研的Redis集群。指标集群节点数多大16*2即16对主从形成的集群,迁徙过程很顺利,通过筹备15分钟实现利用割接。 (迁徙部署图) 通过理论场景的打磨,咱们陆续修复了一些测试中很难遇到的bug,增加了一些新个性。使得产品不仅反对降级迁徙同时反对降级迁徙;为了进步用户体验,咱们参考Redis、MySQL等优良开源产品的形式做了一个命令行客户端命名为redissyncer-cli。至此,实现了RedisSyncer3.X的降级,这个我的项目的体系建设基本上能够满足Redis迁徙同步场景中的大部分需要了。 不止于此,冲破翻新 起初,咱们把RedisSyncer定位为一个Redis的同步工具。随着开发和用户侧的实际,咱们下一步想把RedisSyncer打造成为具备企业级灾备能力的Redis数据同步中间件。从工具到具备企业级灾备能力还是有肯定门槛的。所以下一步咱们的工作重点是对软件进行分布式革新,最终目标是在任意节点产生故障时工作可自动化继续,实现企业级灾备能力的Redis数据同步中间件。 拥抱开源,容纳凋谢 目前京东云曾经积攒了笼罩互联网、游戏、金融、物流、批发等多场景畛域的迁徙教训。随着混合多云趋势到来,咱们深知用户迁徙之苦,也违心以兼容凋谢的心态为客户提供技术服务,真正做到把选择权交给用户,同时为了让更多人享受技术带来的便当,咱们将自研RedisSyncer齐全开源(开源地址:https://github.com/TraceNatur...),将技术回归社区,给更多用户和开发者带来便当!

September 2, 2022 · 1 min · jiezi

关于中间件:得物数据库中间件平台彩虹桥演进之路

前言随着得物 App 用户开始快速增长,业务线日趋丰盛,也对底层数据库带来了较大的压力。各个业务线对于数据分片、读写拆散、影子库路由等等的需要成为了刚需,所以须要一个对立的中间件来撑持这些需要,得物“彩虹桥”应运而生。 在北欧神话中,彩虹桥是连结阿斯加德(Asgard)【1】和 米德加尔特(中庭/Midgard)的微小彩虹桥。咱们能够把它当作是“九界之间”的连贯通道,也是进入阿斯加德的惟一稳固入口。而得物的彩虹桥是连贯服务与数据库之间的数据库中间层解决中间件,能够说得物的每一笔订单都与它非亲非故。 1. 技术选型后期咱们调研了Mycat、ShardingSphere、kingshard、Atlas等开源中间件,综合了适用性、优缺点、产品口碑、社区活跃度、实战案例、扩展性等多个方面,最终咱们抉择了ShardingSphere。筹备在ShardingSphere的根底上进行二次开发、定制一套适宜得物外部环境的数据库中间件。 Apache ShardingSphere 是一款开源分布式数据库生态我的项目,由 JDBC、Proxy 和 Sidecar(布局中) 3 款产品组成。其外围采纳可插拔架构,通过组件扩大性能。对上以数据库协定及 SQL 形式提供诸多加强性能,包含数据分片、拜访路由、数据安全等;对下原生反对 MySQL、PostgreSQL、SQL Server、Oracle 等多种数据存储引擎。ShardingSphere 已于2020年4月16日成为 Apache 软件基金会的顶级我的项目,并且在寰球多个国家都有团队在应用。 目前咱们次要是ShardingSphere的Proxy模式提供服务,后续将会在JDBC&Proxy混合架构持续摸索。 2.彩虹桥目前的能力 其中红色模块为现阶段以及具备的能力,绿色模块为布局&正在做的性能。上面介绍一下几个重点性能。留神,以下性能都是基于Proxy模式。 2.1 数据分片数据分片指依照某个维度将寄存在繁多数据库中的数据扩散地寄存至多个数据库或表中以达到晋升性能瓶颈以及可用性的成果。数据分片的无效伎俩是对关系型数据库进行分库和分表。分库和分表均能够无效地防止由数据量超过可接受阈值而产生的查问瓶颈。除此之外,分库还可能用于无效地扩散对数据库单点的访问量;分表尽管无奈缓解数据库压力,但却可能提供尽量将分布式事务转化为本地事务的可能,一旦波及到跨库的更新操作,分布式事务往往会使问题变得复杂。应用多主多从的分片形式,能够无效地防止数据单点,从而晋升数据架构的可用性。 通过分库和分表进行数据的拆分来使得各个表的数据量放弃在阈值以下,以及对流量进行疏导应答高访问量,是应答高并发和海量数据系统的无效伎俩。数据分片的拆分形式又分为垂直分片和程度分片。 依照业务拆分的形式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用。彩虹桥次要提供的分片能力是程度分片,程度分片又称为横向拆分。绝对于垂直分片,它不再将数据依据业务逻辑分类,而是通过某个字段(或某几个字段),依据某种规定将数据扩散至多个库或表中,每个分片仅蕴含数据的一部分。例如:依据主键分片,偶数主键的记录放入 0 库(或表),奇数主键的记录放入 1 库(或表),如下图所示。 程度分片从实践上冲破了单机数据量解决的瓶颈,并且扩大绝对自在,是数据分片的规范解决方案。 当然理论应用场景的分片规定是非常复杂的,咱们提供一些内置算法比方取模、HASH取模、主动时间段分片算法、Inline表达式等。当内置算法无奈满足要求时,还能够基于groovy来定制专属的分片逻辑。 2.2 读写拆散面对日益减少的零碎访问量,数据库的吞吐量面临着微小瓶颈。对于同一时刻有大量并发读操作和较少写操作类型的利用零碎来说,将数据库拆分为主库和从库,主库负责解决事务性的增删改操作,从库负责解决查问操作,可能无效的防止由数据更新导致的行锁,使得整个零碎的查问性能失去极大的改善。通过一主多从的配置形式,能够将查问申请平均地扩散到多个数据正本,可能进一步地晋升零碎的解决能力。 与将数据依据分片键打散至各个数据节点的程度分片不同,读写拆散则是依据 SQL 语义的剖析,将读操作和写操作别离路由至主库与从库。 这里配置的形式比较简单,给指标主库绑定一个或多个从库、设置对应的负载平衡算法即可。 这里的实现形式就是通过SQL解析,把查问语句路由到对应的从库即可,然而在一些对主从同步提早比拟敏感的场景,可能须要强制走主库,这里咱们也提供一个API(原理就是SQL Hint),让上游能够指定某些模块读强制走主,还有相干全局配置能够让事务内所有读申请全副走主。 2.3 影子库压测在基于微服务的分布式应用架构下,业务须要多个服务是通过一系列的服务、中间件的调用来实现,所以单个服务的压力测试已无奈代表实在场景。在测试环境中,如果从新搭建一整套与生产环境相似的压测环境,老本过高,并且往往无奈模仿线上环境的复杂度以及流量。因而,业内通常抉择全链路压测的形式,即在生产环境进行压测,这样所取得的测试后果可能精确地反馈零碎实在容量和性能程度。 全链路压测是一项简单而宏大的工作。须要各个微服务、中间件之间配合与调整,以应答不同流量以及压测标识的透传。通常会搭建一整套压测平台以实用不同测试计划。在数据库层面须要做好数据隔离,为了保障生产数据的可靠性与完整性,须要将压测产生的数据路由到压测环境数据库,避免压测数据对生产数据库中实在数据造成净化。这就要求业务利用在执行 SQL 前,可能依据透传的压测标识,做好数据分类,将相应的 SQL 路由到与之对应的数据源。 这里配置的形式相似读写拆散,也是给指标主库绑定一个影子库,当SQL携带了影子标就会被路由到影子库。 2.4 限流&熔断当DB的压力超过本身水位线时,会导致DB产生故障。当咱们预估出某个维度的水位线后,能够配置对于的限流规定,回绝掉超过自身水位线以外的申请来爱护DB。让零碎尽可能跑在最大吞吐量的同时保证系统整体的稳定性。维度方面咱们反对DB、Table、SQL以及DML类型。 彩虹桥上面连贯了上百个RDS实例,每个RDS实例都有可能呈现各种故障,当单个实例呈现故障会影响到整个逻辑库,会迅速造成阻塞诱发雪崩效应。所以咱们须要一种疾速失败的机制来避免雪崩,目前咱们是反对DB实例级别的熔断,基于获取连贯&SQL执行2种行为,以及执行工夫跟失败比例来实现熔断,以达到在DB故障时疾速失败的成果。 2.5 流量纠偏在双活架构下,彩虹桥作为数据库的代理层,能够保障双活架构下流量切换过程的流量做兜底拦挡,保证数据一致性。原理就是基于SQL Hint携带的userId与机房规定做匹配,拦挡不属于以后机房的流量。 3. 基于ShardingSphere咱们做了哪些革新尽管ShardingSphere Proxy自身其实曾经足够弱小,然而针对得物外部环境,还是存在一些缺点和性能缺失,次要分为以下几点: 易用性 a.分片、读写拆散等规定配置文件过于简单,对于业务开发不够敌对 b.规定动静变更齐全依赖配置核心,缺失欠缺的变更流程 c.连接池治理能力不欠缺 d.Hint形式不够敌对,须要业务写RAL语句 e.自定义分片算法须要公布 f.SQL兼容性稳定性 a.多集群治理性能缺失 b.逻辑库之间的隔离性缺失 c.限流熔断组件缺失 d.数据源、规定动静变更有损 e.双活架构下流量纠偏性能的缺失 f.公布有损可观测性 a.SQL Trace性能不欠缺 b.监控指标不够全面 c.SQL洞察能力缺失性能 因为多了一次网络转发,单条SQL的RT比直连会上浮2~3ms为了解决以上问题,咱们做了以下革新与优化。 ...

July 14, 2022 · 1 min · jiezi

关于中间件:云原生时代中间件应该如何-进化

云原生热度继续攀升,这一趋势也延长了到中间件畛域。借助云原生技术,中间件正在解决了本身的弹性、韧性、运维、交付等问题。同时,开发者应用中间件形式也越来越云原生化。 那么,在云原生时代,中间件应该如何实现本人的技术 “进化” 呢?5 月 30 日,网易数帆云原生首席架构师冯常健做客《极客有约》,与咱们一起探讨了这一话题。以下内容依据直播内容整顿,并做了不扭转原意的删减,残缺内容[[可点击查看回放视频]](https://www.infoq.cn/video/Zq...) 6 月 22 日 19:00-20:30,数字化根底软件自主翻新分享周・中间件技术论坛,3 位专家解读云原生中间件高稳固、高性能、高可用实际,欢送关注:多元共生 连贯新机 - 2022 网易数帆数字化根底软件自主翻新分享周 中间件为什么要云化Q:冯老师 12 年退出网易,曾经有十多年的研发教训。您是什么时候开始关注云原生的? A:我大略做了十多年的开发和架构设计工作,比拟侥幸的是,我正好残缺地赶上了云原生从萌芽、倒退,再到目前逐步成熟,在生产环境里能够大规模翻新落地的整个过程。在 2014 年的时候,Kubernetes1.0 版本还没有进去,咱们就基于 Docker、Kubernetes 开发容器云平台。目前,我在公司外面也始终在做云原生相干的微服务、容器化、服务网格、中间件以及 DevOps 等云原生工程大规模落地实际方面的事件。 Q:您感觉,云原生从最开始到当初产生了哪些重大进展? A:最直观的感触还是云原生对研发运维过程产生了很大的影响。5、6 年前,DevOps 还没有太多比拟具体的落地门路,更多还是在强调 DevOps 开发运维一体化的理念。随着云原生各项技术的倒退,大家缓缓发现 DevOps 理念提倡的麻利、灵便和疾速,都能够通过云原生技术落地。能够说,云原生技术真正重塑了企业开发和运维的整个过程。 Q:那中间件云化的必要性体现在哪里? A:首先,云的基本特色就是具备资源弹性,能够应答突发性的流量稳定,而弹性的背地就是资源的池化,即把所有的计算、网络、存储等做成一个资源池,咱们能够充沛地调度,来晋升资源利用率。 第二方面,我感觉自动化运维方面是绕不过来的。在传统畛域,如果不做云化和平台化,依照咱们的工程教训,通过脚本或半自动化形式能够搞定三五十个集群。但当数量达到互联网业务常见的三五百个集群规模后,传统脚本或半自动化形式是很难掌控这么多实例稳固运行的。云化的必要性在于,它能够很好地解决自动化运维的问题。 第三方面,标准化也是云化必要性的一个体现。如果不思考云原生化,咱们实际上会面临特地多的版本,特地是中间件畛域,同一个中间件的选型会有很多版本,另外还有很多不同的部署架构,自动化各方面能力也难以对立。 而云化就意味着绝对标准化,有助于技术栈的对立。咱们能够把整个技术栈聚焦到少数几个选型上,还能够进一步做企业级的技术规范化,大家约定应用某个版本后会便于后续的保护和对立降级。 还有一点,云化意味着中间件服务供应形式的变动。规模化组织里,微服务架构除了利用外,还须要缓存、音讯队列等中间件。这样的中间件要做微服务,首先要申请流程,如果运维团队和业务团队不是一个老本核心,还须要提前做容量布局、采购计划等等。这个过程波及了多方大量的流程性交互。 云化的中间件平台提供了一个技术中台,或者说是一个门户,能够自主申请,通过一些必要的审批之后,各业务部门本人能够按需采纳,大大缩短了流程,使整个资源管控效率更高。 Q:什么样的中间件能够称之为云原生的中间件? A:我认为运行在 K8s 下面,用 K8s 原生的形式设计架构的中间件服务,就是云原生的中间件。 Q:云原生中间件和本地 PaaS 中间件之间是否有实质上的不同? A:差别起源是云原生中间件基于 K8s。中间件的很多根底能力都下沉到了 K8s,大量惯例的高频运维操作都被形象成 K8s 下面一个个资源的定义,运维人员常常碰到的扩缩容、迁徙、重建、故障复原等高频动作都能够通过 kubectl 或其余对应的白屏化操作对立操作,极大升高了运维门槛和工作量,这是标准化带来的一个益处。 另外,因为有 Kubernetes 这一层形象,云原生中间件人造能够做跨云或者跨异构基础设施的部署交互,所以用户体验能够在整个过程中放弃完全一致。也就是说,在云计算时代,咱们能够抉择不同的国内外支流云厂商,把中间件服务齐全跑在云上,而且能够随时迁徙。这些实践上就是基于 Kubernetes 这一层的解耦。 中间件的云化门路Q:云原生中间件的技术栈次要涵盖了哪些?又如何通过对企业倒退起到降本增效的作用? A:咱们整个技术栈次要基于 K8s 以及 K8s 下面的框架,比方 Operator 等。 ...

June 17, 2022 · 2 min · jiezi

关于中间件:得物技术消息中间件应用的常见问题与方案

1. 引言音讯队列(MQ)中间件曾经遍及很多年了,在互联网利用中,通常稍大一些的利用,咱们都能够见到MQ的身影。以后市面上有很多中消息中间件,包含但不限于RabbitMQ、RocketMQ、ActiveMQ、Kafka(流解决中间件) 等。很多开发人员曾经纯熟的把握了一个或者多个消息中间件的应用。然而依然有一些小伙伴们对消息中间件不是特地相熟,因为各种起因不能深刻的去学习理解个中原理和细节,导致应用的时候可能呈现这样那样的问题。在这里,咱们就针对音讯队列中间件应用中的典型问题作一番剖析(包含程序音讯、可靠性保障、音讯幂等、延时音讯等),并提供一些解决方案。 2. 消息中间件利用背景2.1 消息中间件根本思维咱们在单个零碎中,一些业务解决能够程序顺次的进行。而波及到跨零碎(有时候零碎外部亦然)的时候,会产生比较复杂数据交互(也能够了解为消息传递)的需要,这些数据的交互传递形式,能够是同步也能够是异步的。在异步传递数据的状况下,往往须要一个载体,来长期存储与散发音讯。在此基础上,专门针对音讯接管、存储、转发而设计与开发进去的业余应用程序,都能够了解为音讯队列中间件。 引申一下:如果咱们本人简略的应用一张数据库表,来记录数据,而后承受数据存储在数据表,通过定时工作再将数据表的数据散发进来,那么咱们曾经实现了一个最简略的音讯零碎(这就是本地音讯表)。 咱们能够认为消息中间件的根本思维就是 利用高效牢靠的消息传递机制进行异步的数据传输。在这个根本思维的领导下,不同的音讯两头,因为其偏重场景目标不同,在性能、性能、整体设计理念上又各有差异。 音讯队列(MQ)自身是实现了生产者到消费者的单向通信模型,RabbitMQ、RocketMQ、Kafka这些罕用的MQ都是指实现了这个模型的消息中间件。目前最罕用的几个消息中间件次要有,RabbitMQ、RocketMQ、Kafka(分布式流解决平台)、Pulsar(分布式音讯流平台)。这里我将两个流解决平台纳入其中了, 更早的一些其余消息中间件曾经缓缓淡出视线。业务选型的时候咱们遵循两个次要的准则:最大相熟水平准则(便于运维、应用牢靠)、业务符合准则(中间件性能能够撑持业务体量、满足业务性能需要)。 这几个罕用的消息中间件选型比照,很容易找到,这里就不详细描述了。大略说一下:Pulsar目前用的不如 RabbitMQ、RocketMQ、Kafka多。RabbitMQ次要并重是高可靠消息,RocketMQ性能和性能并重,Kafka次要是在大数据处理中利用比拟多(Pulsar比拟相似)。 2.2 引入消息中间件的意义咱们先简略举例介绍一下异步、解藕、削峰的意义与价值(参考上面这张流程图): 对于一个用户注册接口,假如有2个业务点,别离是注册、发放新人福利,各须要50ms去解决逻辑。如果咱们将这两个业务流程耦合在一个接口,那么总计须要100ms解决实现。然而该流程中,用户注册时候,能够不必关怀本人的福利是否立刻发放,只有尽快注册胜利返回数据即可,后续新人福利这一部分业务能够在主流程之外解决。咱们如果将其剥离进去,接口主流程中只解决登陆逻辑,并通过MQ推送一条音讯,通过异步形式解决后续的发放新人福利逻辑,这样即可保障注册接口50ms左右即能获取后果。而发放新人福利的业务,则通过异步工作缓缓解决。 通过拆分业务点,咱们曾经做到解耦,注册的从属业务中减少或缩小性能点都不会影响主流程。另外如果一个业务主流程在某个点申请并发比拟高,正好通过异步形式,能够将压力扩散到更长的时间段中去,达到加重固定时间段解决压力的目标,这就是流量削峰。 **另外,单线程模型的语言,通常对消息中间件的需要更强烈。多线程模型的语言,或者协程型语言,尽管能够通过本身的多线程(或协程)机制,来实现业务外部的异步解决,然而思考到长久化问题以及治理难度,还是成熟的中间件更适宜用来做异步数据通信,中间件还能实现分布式系统之间的数据异步通信。 2.3 消息中间件的利用场景消息中间件的利用场景次要有: 异步通信:能够用于业务零碎外部的异步通信,也能够用于分布式系统信息交互零碎解耦:将不同性质的业务进行隔离切分,晋升性能,主附流程分层,依照重要性进行隔离,缩小异样影响流量削峰:间歇性突刺流量扩散解决,缩小零碎压力,晋升零碎可用性分布式事务一致性:RocketMQ提供的事务音讯性能能够解决分布式事务一致性(如电商订单场景)。当然,也能够应用分布式事务中间件。音讯程序收发:这是最根底的性能,先进先出,音讯队列必备延时音讯: 提早触发的业务场景,如下单后提早勾销未领取订单等大数据处理:日志解决,kafka分布式缓存同步:生产MySQLbinlog日志进行缓存同步,或者业务变动间接推送到MQ生产所以,如果你的业务中有以上列举的场景,或者相似的性能、性能需求,那么快快引入 消息中间件来晋升你的业务性能吧。 3. 引入消息中间件带来的一系列问题尽管消息中间件引入有以上那么多益处,然而应用的时候仍然会存在很多问题。例如: 引入消息中间件减少了零碎复杂度,怎么应用保护音讯发送失败怎么办(音讯失落)为了确保能发胜利,音讯反复发送了怎么办(音讯反复)音讯在中间件流转出现异常怎么解决音讯生产时候,如果生产流程失败了怎么解决,还能不能从新从中间件获取到这条音讯生产失败如果还能获取,那会不会呈现失败状况下,始终反复生产同一条音讯,从而流程卡死生产失败如果不能再获取,那么咱们该怎么确保这条音讯能再次被解决反复生产到雷同的音讯流程怎么解决,会不会导致业务异样那么咱们该怎么确保生产流程只胜利执行一次对于那些有程序的音讯咱们应该怎么保障发送和生产的程序统一音讯太多了,怎么保障生产脚本生产速度,以便更得上业务的解决需要,防止音讯有限积压我想要发送的音讯,等上几秒钟的工夫再生产到,该怎么做当然咱们对于以上的这些问题,针对业务开发者来说,能够进行提炼,失去以下几个重点问题: 音讯程序性保障防止音讯失落音讯的反复问题音讯积压解决提早音讯解决4. 问题的解决方案4.1 音讯程序性保障惯例的消息中间件和流解决中间件,自身设计个别都能反对程序音讯,然而依据中间件自身不同的设计指标,有不同的原理架构,导致咱们业务中应用中间件的时候,要针对性做不同的解决。 以下几个罕用音讯或流中间件的程序音讯设计以及应用中乱序问题剖析: RabbitMQ: RabbitMQ的单个队列(queue)本身,能够保障音讯的先进先出,在设计上,RabbitMQ所提供的单个队列数据是存储在单个broker节点上的,在开启镜像队列的状况下,镜像的队列也只是作为音讯正本而存在,服务仍然由主队列提供。这种状况下在单个队列上进行生产,人造就是程序性的。不过因为单个队列反对多消费者同时生产,咱们在开启多个消费者生产对立队列上的数据时候,音讯扩散到多个消费者上,在并发高的时候,多个消费者无奈保障解决音讯的程序性。 解决办法就是对于须要强制程序的音讯,应用同一个MQ队列,并且针对单个队列只开启一个消费者生产(保障并发解决时候的程序性,多线程同理)。由此引发的单个队列吞吐降落的问题,能够采取kafka的设计思维,针对繁多工作开启一组多个队列,将须要程序的音讯依照其固定标识(例如:ID)进行路由,扩散到这一组队列中,雷同标识的音讯进入到雷同的队列,单个队列应用单个消费者生产,这样即能够保障音讯的程序与吞吐。 如图所示: Kafka: Kafka是流解决中间件,在其设计中,没有队列的概念,音讯的收发依赖于Topic,单个topic能够有多个partition(分区),这些partition能够扩散到多台broker节点上,并且partition还能够设置正本备份以保障其高可用。 Kafka同一个topic能够有多个消费者,甚至生产组。Kafka中音讯生产个别应用生产组(生产组能够互不干涉的生产同一个topic下的音讯)来进行生产,生产组中能够有多个消费者。同一个生产组生产单个topic下的多个partition时,将由kafka来调节生产组中消费者与partiton的生产进度与平衡。然而有一点是能够保障的:那就是单个partition在同一个生产组中只能被一个消费者生产。 以上的设计理念下,Kafka外部保障在同一个partition中的音讯是程序的,不保障topic下的音讯的程序性。Kafka的音讯生产者发送音讯的时候,是能够抉择将音讯发送到哪个partition中的,咱们只有将须要程序解决的音讯,发送到topic下雷同的partition,即可保障音讯生产的程序性。(多线程语言应用单个消费者,多线程解决数据时,须要本人去保障解决的程序,这里略过)。 RocketMQ: RocketMQ的一些基本概念和原理,能够通过阿里云的官网做一些理解:什么是音讯队列RocketMQ版? - 音讯队列RocketMQ版 - 阿里云 。 RocketMQ的音讯收发也是基于Topic的,Topic下有多个 Queue, 散布在一个或多个 Broker 上,用来保障音讯的高性能收发( 与Kafka的Topic-Partition机制 有些相似,但外部实现原理并不相同 )。 RocketMQ反对部分程序音讯生产,也就是保障同一个音讯队列上的音讯程序生产。不反对音讯全局程序生产,如果要实现某一个主题的全局程序音讯生产,能够将该主题的队列数量设置为1,就义高可用性。具体图解能够参考阿里云文档: 程序音讯2.0 - 音讯队列RocketMQ版 - 阿里云 4.2 防止音讯失落音讯失落须要分为三局部来看:音讯生产者发送音讯到消息中间件的过程不产生音讯失落,音讯在消息中间件中从承受存储到被生产的过程中音讯不失落, 音讯生产的过程中保障能生产到中间件发送的音讯而不会失落。 生产者发送音讯不失落: 消息中间件个别都有音讯发送确认机制(ACK), 对于客户端来说,只有配置好消息发送须要ACK确认,就能够依据返回的后果来判断音讯是否胜利发送到中间件中。这一步通常与中间件的音讯承受存储流程设计有关系。依据中间件的设计,咱们通常采取的措施如下: 开启MQ的ACK(或confirm)机制,间接获知音讯发送后果开启音讯队列的长久化机制(落盘,如果须要非凡设置的话)中间件自身做好高可用部署音讯发送失败弥补设计(重试等)在具体的业务设计中,如果音讯发送失败,咱们能够依据业务重要水平,做相应的弥补,例如: 音讯失败重试机制(发送失败,持续重发,能够设置重试下限)如果仍然失败,依据音讯重要性,抉择降级计划:间接抛弃或者降级到其余中间件或载体(同时须要相应的降级弥补推送或生产设计)消息中间件音讯不失落: ...

May 11, 2022 · 1 min · jiezi

关于中间件:开源进展-WeBASE-v154-发布新增实训案例集与管理台操作指引

作为一个敌对的、功能丰富的区块链中间件平台,WeBASE始终致力于升高区块链开发者的研发门槛,进步区块链开发效率。 现在,WeBASE v1.5.4来了,此次更新新增区块链利用实训课程案例集,以及治理台操作指引与设计说明,助力社区开发者更快捷高效地学习区块链,搭建区块链利用。一起来看看v1.5.4带来的新性能吧! 新增实训课程案例集如何将 WeBASE与区块链课程相结合,以更好地服务开发者?为解答这一命题, WeBASE团队和社区搭档、社区开发者通力合作,对WeBASE性能进行有针对性的调整,在WeBASE v1.5.1中推出WeBASE实训插件,反对教学实训场景,详情见《开源停顿 | WeBASE v1.5.1 公布,反对教学实训场景》。 在本次v1.5.4的更新中,WeBASE技术文档新增了“WeBASE实训课程案例”板块,收录的课程案例均为针对社区实训课程专门设计的,案例实现由实训题目、试验步骤和参考答案三个模块组成。 目前收录了从易到难的三个案例:运行第一个智能合约,积分转账合约实现,存证合约利用实现。开发者能够参考案例疾速上手合约开发,社区搭档能够参考案例,依据本身理论课程设计进行相应调整。 实训题目:形容了本次课程的具体要求。 如下图1所示,“运行第一个智能合约”的要求为:应用Solidity语言编写一个HelloWorld合约,阐明该合约需蕴含哪些合约逻辑,实现怎么的成果,并给出了合约的根底框架。图1:创立第一个智能合约-实训题目 试验步骤:形容了实训所需的各试验步骤,每个试验步骤会给出对应的答案“提交形式”要求,也就是在实现试验步骤后,须要提交哪些内容。如下图2所示,“向部署的智能合约发送交易”这一步骤中,咱们依据学生在该课程所须要把握的知识点,列出了须要其提交的内容。比方,须要学生把握通过SDK连贯节点的知识点,则要求学生提交通过SDK连贯节点的源码。阐明一下,此处试验步骤和提交内容能够依据自定义的课程内容进行调整。图2:创立第一个智能合约-局部试验步骤 参考答案:WeBASE提供了一套基于FISCO BCOS和WeBASE实现的课程参考答案,蕴含了实现的源代码、试验步骤截图等。将来,WeBASE 团队将继续开掘 WeBASE 在区块链教育领域中的潜能,也欢送各位社区开发者参加共建,发明更多元化的实训课程案例奉献到社区。 WeBASE治理台新增操作指引本次更新中,WeBASE治理台各页面新增了【操作指引】,对页面模块性能的设计与应用办法进行阐明,不便用户疾速相熟、把握WeBASE。如下图3所示,在WeBASE “私钥治理”页面中,用户能够通过页面右侧的【操作指引】,疾速理解“新增用户”和“导入私钥”两个按钮的性能是什么,把握其应用办法。图3:WeBASE治理台-私钥治理页面 又如,可能有用户会纳闷为什么本人的私钥或者合约会被WeBASE标记为“异样”, 呈现“用户异样”或者“合约异样”的告警。 如下图4所示,用户“0x97e9b7a9d5e19a8a0aa7cd39f632244da69640b6”被WeBASE标记为异样用户,呈现在“交易审计-异样用户”的告警列表中。在v1.5.4新增操作指引后,用户能够在WeBASE治理台“交易审计-异样用户” 页面右侧操作指引中,疾速查看交易审计性能的设计与应用阐明,理解其被标记为“异样用户”起因为:该私钥用户在链上发动过交易,然而并没有在WeBASE的私钥治理中注销。*只有某个私钥在链上发动了交易,或者某个合约部署到链上了然而未在WeBASE中注销,那么对应的私钥地址或合约地址即会被WeBASE标记为“异样”。 图4:WeBASE治理台-交易审计-异样用户页面 实际上,咱们在“私钥治理-全量”用户列表中能看到该用户,阐明该用户的确在链上发动过交易(如未发动过交易的私钥无奈在全量用户列表中看到)。依照“交易审计-异样用户”的操作指引所形容,用户只须要在全量用户“导入”该私钥的地址到WeBASE中,或者将该用户地址对应的私钥导入到WeBASE中,即可打消“用户异样”的告警。 图5:WeBASE治理台-私钥治理页面 其余优化和修复 优化:优化WeBASE治理台的合约IDE交易体验,丰盛入参提醒,如bytesN类型提醒输出长度并校验参数。 优化:新增WeBASE治理台中登录页“遗记明码“与”验证码加载失败“提醒。 优化:优化合约仓库加载形式,通过conf/warehouse目录中的.json文件可加载合约模板;社区用户能够间接依照json格局,提交Pull Request奉献合约。 优化:更新可视化部署的build_chain脚本为最新的v2.8.0,修复openssl版本兼容性问题。 bugfix:修复WeBASE所调用的Java-SDK的KeyFactory肯定状况下反复私钥的问题。bugfix:修复查问event页面中获取合约列表,合约反复问题。bugfix:修复可视化部署中检测localhost的误判。 即刻应用上述优化及性能所波及的最新代码和技术文档已同步更新,欢送体验和star反对。如需征询技术问题,欢送本公众号对话框回复【小助手】进技术交换群。 WeBASE 代码仓库:https://github.com/WeBankBloc...WeBASE 代码仓库国内镜像:https://gitee.com/WeBank/WeBASE/WeBASE 技术文档:https://webasedoc.readthedocs...WeBASE 技术文档国内镜像:https://osp-1257653870.cos.ap... 首次体验WeBASE,可参考一键部署文档:https://webasedoc.readthedocs...如需降级已有版本,可参考:WeBASE一键部署的一键降级:https://webasedoc.readthedocs...WeBASE-Front降级阐明:https://webasedoc.readthedocs...WeBASE-Node-Manager降级阐明:https://webasedoc.readthedocs...WeBASE-Sign降级阐明:https://webasedoc.readthedocs...WeBASE-Web降级阐明:https://webasedoc.readthedocs...向咱们报告问题,欢送提交issue:https://github.com/WeBankFinT... 理解更多干货内容,请关注FISCO BCOS开源社区公众号,拜访FISCO BCOS代码仓库可下载我的项目所有源代码:https://github.com/FISCO-BCOS/FISCO-BCOS,欢送点击页面右上角star珍藏,获取最新版本。

April 11, 2022 · 1 min · jiezi

关于中间件:始于信任-忠于专业-|-DataPipeline收到一封来自山东城商行联盟的感谢信

近期,DataPipeline收到一封来自山东省城市商业银行单干联盟有限公司(以下简称:山东城商行联盟)的感谢信。客户对DataPipeline全力以赴、恪尽职守的工作态度及做出的踊跃奉献给予高度肯定和感激,并对后续工作提出了殷切期望。收到这封信,相干我的项目组成员都备受鼓励。 信里这样写到: “贵司依照联盟我的项目要求,积极响应、被动工作、密切配合,顺利完成了2021年我的项目打算工作,确保了联盟金融云数据中心建设项目工作的安稳顺利推动。在此期间,贵司委派加入联盟我的项目施行工作的王鑫同志,严格执行联盟我的项目工作的各项打算和要求,认真负责、恪尽职守、不辞辛苦,为保障工作的顺利完成做出了踊跃的奉献。 在此,对贵司给予联盟金融云数据中心建设项目的高度重视和全力以赴示意衷心感谢,并心愿贵司依照我的项目工作打算和要求再接再厉,为联盟金融云数据中心建设及迁徙我的项目的发展持续提供无力反对。” / 业务当先理念符合,拥抱实时数据管理早在2020年,山东城商行联盟就开启了与DataPipeline的单干之路。 山东城商行联盟经原中国银监会批准成立,是目前全国惟一持有金融牌照的中小银行金融科技服务公司。公司为各成员行提供集外围业务零碎、互联网金融零碎、外联业务平台、大数据服务及经营、风控反对等全方位的信息科技解决方案以及培训、征询、单干翻新等多元服务,引领成员行通过科技翻新推动业务倒退和转型降级,是山东省大数据重点骨干企业。公司致力于打造赋能中小银行、凋谢共享的金融科技生态平台。 在云计算、大数据、人工智能疾速倒退背景下,金融行业适应客户须要的多样化和个性化场景不断涌现。通过10多年的电子化倒退、信息化建设,山东城商行联盟积攒了海量的数据,如何利用好这些数据成为了联盟应答新局势挑战、谋求转型倒退的重要课题。绝对于大型商业银行,升高经营老本、晋升客户体验、进步营销能力等转型工作对于以山东城商行联盟为代表的的城市商业银行在科技翻新倒退上更为要害。 随着数据利用的深刻,成员行业务部门一直提出更简单的实时数据加工需要,新需要的加工复杂度继续升高、应用场景继续扩大、交付效率继续放慢、经营品质要求继续晋升。为晋升实时数据撑持能力,山东城商行联盟开始启动实时数据体系建设,在不影响外围业务的状况下,将外围业务的数据准实时进行数据散发,全面推动“业务监测与危险预警、智慧APP6.0、智慧营销平台”等业务的能力。 山东城商行联盟通过产品调研、可行性剖析、POC验证,抉择DataPipeline数见科技作为合作伙伴共同完成数据库实时数据采集零碎我的项目的施行。该计划三大外围能力与联盟实时数据管理体系整体策略高度符合: 01 多元异构 Oracle、IBM DB2、MySQL、Kafka等多种数据库进行近实时的数据采集性能,并对数据源建设高效的治理性能,实现对数据源、目的地的数据连贯对立治理治理,通过界面进行数据源与目的地注册,删除数据源,同时依据需要一直迭代反对新的数据库。 02 实时同步 利用解析数据库归档日志的形式,实现秒级的数据变更捕捉,将解析的变更记录传送到数据目的地中,包含日志中提取数据变更的增、删、改等DML操作记录,以及新增表、删除表、增加字段、删除字段等主动同步到目的地中。 03 规范治理 对立的可视化治理页面,提供平台级别的数据管理性能,包含产品权限、数据时效治理和平安管控等方面性能,为数据工程师、运维人员提供直观的数据工作地图,随时能够洞悉数据的最新动静,极大晋升运维工作效率和效益。 精诚合作顺利上线,构建松软底座我的项目现场 自零碎建设启动以来,多研发测试工作齐头并进,山东城商行联盟生产运维部及DataPipeline项目组全体成员高度重视、上下一心通力协作,顺利完成上线测试。针对割接计划,我的项目组成员进行多轮评审,精心筹备、思考周全,最终确保割接工作精确有序进行,数据及业务零碎十拿九稳,我的项目圆满完成。该零碎已于2021年正式投入使用。 山东省城商行联盟外围运维组技术专家倪俊甜在DataPipeline2021数据管理与翻新大会的演讲中示意: “ DataPipeline助力山东省城商行联盟构建的企业级数据库准实时数据采集零碎对于推动其实现数字化转型、数据规范化和集约化治理、赋能企业经营及加强其长久外围竞争力具备重要意义。DataPipeline可实现数据的秒级实时采集,产品具备对立易用的人性化操作界面,丰盛的配置策略可实现对资源的高效充分利用,产品同时具备标准化遵循与前瞻性判断前提下的凋谢可扩展性,当然最重要的是其金融级的稳固高容错能力。” 全域数据实时交融的价值愈发重要,是减速数据流通、从而晋升经营效率构建差异性竞争劣势的重要伎俩。该我的项目平台实现各零碎的买通与关联,笼罩多层次客户服务体系,强化了线上业务服务和资产配置等综合实力。该项目标施行晋升了成员行的获客能力和精准个性化服务水平,助力成员行经营与治理数智化再降级。同时,简略易用的数据同步机制能够升高应答各种实时数据利用场景的老本,进步数据的复用度,高效开释数据价值。 因而,同年12月,「DataPipeline助力山东城商行联盟构建企业级数据库准实时数据采集零碎」案例胜利入选由中国信息协会公布的“2021中国大数据利用样板100例”,取得来自多方的好评,起到行业示范引领效应。 在该我的项目后续阶段,DataPipeline也将会持续施展产品技术与服务劣势,以高水平、高要求的规范实现接下来的工作工作。 “客户胜利”是DataPipeline企业文化理念中的重点。DataPipeline向所有信赖和反对公司的客户示意衷心感谢,同时也向事必躬亲地践行着公司愿景与使命的DataPipeline人致以敬意。将来,DataPipeline将充分发挥在实时数据管理畛域的当先劣势,继续深耕金融等行业,推动产业高质量倒退。

March 1, 2022 · 1 min · jiezi

关于中间件:Dubbogo-v30-正式发布-打造国内一流开源-Go-服务框架

简介:Dubbo-go 是常新的,每年都在一直进化。介绍 Dubbo-go 3.0 工作之前,先回顾其过往 6 年的倒退历程,以清晰将来的方向。 作者 | 李志信起源 | 阿里技术公众号 作者介绍: 李志信(github @laurencelizhixin),dubbo-go 3.0 负责人,Apache Dubbo PMC,来自阿里云中间件团队,从事 Go 语言中间件的研发和开源工作。于雨 (github @AlexStocks),dubbo-go 社区负责人,Apache Dubbo PMC,蚂蚁团体可信原生部【TNT】基础设施和中间件研发一线程序员。工作十一年来陆续参加和改良过 Redis/Pika/Pika-Port/etcd/Muduo/Dubbo/dubbo-go/Sentinel-golang/Seata-golang 等出名我的项目。 牛学蔚(github @justxuewei),Apache Dubbo Committer,北邮计算机学院二年级研究生,对中间件、云原生畛域有着浓重的趣味。 董剑辉(github @Mulavar),Apache Dubbo Committer,目前次要关注的开源方向为 Dubbo、Flink、Calcite。 Go 语言作为最风行的云原生语言,近些年领有很高的热度,一度备受国内开源生态的关注,据笔者理解,泛滥企业也在近年来从本身传统技术栈转型 Go 语言技术栈。Go 以其开发麻利、易用性高、入门较为容易的劣势深受宽广开发者青眼。而在 Go 语言生态成日益蓬勃发展之势下,其生态的齐备性,相比于饱经考验的 Java 生态仍然有着很大的 Gap,对中小型企业来说,仍然须要相似于 Spring 的 Go 框架来撑持日常业务开发,渴望具备 Dubbo 生态的易用性和稳定性,在这样的诉求之下,初衷为 “Bridging The Gap Between Java And Go” 的 Dubbo-go 服务框架在 2016 年应运而生,倒退至今。 咱们在往年下半年的云计算基础架构大会上理解到了“基础架构能力下沉”的重大意义,从单体架构到云原生架构的一步步倒退,都在致力将业务代码与中间件解耦,尽可能提供对立的编程接口,通过AOP的思路将服务调用抽象化,将接口标准化,将基础设施的实现下沉化。而 Dubbo-go 正是在原有保障网络通信的高可用、稳定性的前提下,整合了一批罕用开源组件,提供统一的编程接口可供扩大和调用。在此之上,对齐 Dubbo 生态支流管制面,尝试与云原生联合,朝向 Proxyless Service Mesh 方向倒退,是咱们整个生态我的项目的统一的愿景。 ...

December 27, 2021 · 5 min · jiezi

关于中间件:数据管理典范山东城商行联盟数据库准实时数据采集系统入选2021中国大数据应用样板案例

12月17日,由中国信息协会大数据分会主办的“2021中国大数据技术利用大会”在北京圆满闭幕。来自中国信息协会、中国工程院、国家信息中心、中国软件评测核心、中国金融认证核心等的权威专家、知名企业代表缺席本次大会,对大数据的需要、利用和产业倒退进行了深度探讨。大会重磅公布“2021中国大数据利用样板100例”,「DataPipeline助力山东城商行联盟构建企业级数据库准实时数据采集零碎」案例胜利入选。 《2021中国大数据利用样板100例》意在表彰2021年度施行的重点大数据标杆案例,案例信息将被呈报到国务院各直属机构信息中心、各省市经济和信息化主管部门、各大央国企等龙头企业、国家及省级产业联盟协会等,为相干部门提供数字化转型计划利用范本及决策参考,并起到行业示范引领效应。 实时数据管理,业务翻新倒退必然保障作为全国惟一持有金融牌照的中小银行金融科技服务公司,山东城商行联盟为中小银行提供全方位的信息科技解决方案以及多元服务,致力于打造赋能中小银行、凋谢共享的金融科技生态平台。 山东城商行联盟认为,中小金融机构是普惠金融的次要力量。以后经济社会互联网化、数字化水平正在疾速加深,普惠金融的生产模式和金融服务供应模式正在产生粗浅变动的局势下,只有借助金融科技的力量,实现传统普惠金融服务与治理、经营模式向数字化普惠金融的转变,能力无效获客、无效管制传统模式下难以管制的金融风险,能力进步普惠金融的服务触达范畴和能力,进而实现普惠金融的可继续倒退。 通过10多年的电子化倒退、信息化建设,山东城商行联盟积攒了海量的数据,如何利用好这些数据成为了联盟应答新局势挑战、谋求转型倒退的重要课题。绝对于大型商业银行,升高经营老本、晋升客户体验、进步营销能力等转型工作对于以山东城商行联盟为代表的的城市商业银行在科技翻新倒退上更为要害。 随着数据利用的深刻,成员行业务部门一直提出更简单的实时数据加工需要,新需要的加工复杂度继续升高、应用场景继续扩大、交付效率继续放慢、经营品质要求继续晋升。为晋升实时数据撑持能力,山东城商行联盟开始启动实时数据体系建设。该体系须要实现综合业务零碎CBUS、外联业务解决平台XBUS、ESB服务总线、电子银行等零碎的数据实时采集、同步、散发。如何买通Oracle、IBM DB2、MySQL、Kafka等多种数据管理技术,实现每日产生的数亿条数据的整合,成为联盟亟待解决的问题。 携手DataPipeline,构筑全域数据管理根底平台松软底座山东城商行联盟在过往服务成员行过程中,业务端在取数时,首先须要将各数据源通过CDC模式将数据实时同步至两头库;其次,源端数据同步至两头库后,通过CDC实时下发至各个上游用数方。在该过程中,因为上游发版频繁,两头库的数据结构均须要相应变动,数据同步过程中系统维护工作量较大地影响了数据利用方的取数时效性。为了可能更好地服务联盟成员行,山东城商行联盟须要从新构建对立的数据库准实时数据采集零碎,实现通过数据流平台近实时地向各外围零碎供数的目标,进而及时高效地反对成员行的经营、市场、销售等实时业务需要。 企业级数据库准实时数据采集零碎架构图 山东城商行联盟通过产品调研、可行性剖析、POC验证,抉择DataPipeline数见科技作为合作伙伴共同完成数据库实时数据采集零碎我的项目的施行。其次要起因为:DataPipeline企业级实时数据交融平台可实现数据的秒级实时采集,产品具备对立易用的人性化操作界面,丰盛的配置策略可实现对资源的高效充分利用,产品同时具备标准化遵循与前瞻性判断前提下的凋谢可扩展性,当然最重要的是其金融级的稳固高容错能力。DataPipeline助力山东省城商行联盟构建的企业级数据库实时数据采集零碎对于推动联盟实现数字化转型、数据规范化和集约化治理、赋能企业经营及加强其长久外围竞争力具备重要意义。计划技术亮点包含: >>稳固高容错具备足够的策略配置与容错机制来应答上下游零碎不稳固带来的不确定性。 1.提供欠缺的构造变动应答策略,可能依照不同的场景进行取舍与配置,从而保障本身的稳定性。 2.领有弱小的反压解决机制和灵便的读取、写入限度配置,能够通过管制读取速率、并行度、批次大小的形式,实现增量数据反压的解决,从而保障本身的稳定性。 3.提供预设策略在无打算的网络不可用、呈现未知异样等状况下进行从新连贯,重置线程乃至重启工作等自动化操作,从而保障本身的稳定性。 >> 便捷可治理具备配置便捷,部署便捷,分层治理,按需服务的可治理个性。 1.配置式链路定义,无代码工作构建,运行治理,运维治理配置化,从原有的研发模式转变为系统配置管理模式。 2.容器化部署、系统资源注册、负载平衡机制和高度配置化的系统资源分组治理。 3.对数据节点注册、数据链路配置、数据工作构建、零碎资源分配等各个环节可能分档次、分用户进行解耦。 4.将数据获取的范畴、数据工作的生命周期、系统资源投入的多寡等配置交给应用数据的人员。 >> 凋谢可扩大凋谢可扩大的前提在于标准化的遵循与技术趋势的前瞻性判断。 1.适应不同的数据管理技术,为用户提供基于开放式、国内通用规范的自定义数据节点。 2.反对不同类型数据节点标准化语义定义,多元异构语义交融,用户能够自定义节点间语义转化关系,保障实时数据交融过程顺利无效。 3.将三类配置解耦,能够在不扭转根本逻辑架构的状况下,实现配置和性能的良好扩大。适应实时数据交融管理机制的一直倒退。 向实时数据要效益,激发经营与治理数智化再降级自我的项目施行以来,零碎实现Oracle、IBM DB2、MySQL、Kafka等多种数据库近实时的数据采集性能,并对数据源建设高效的治理性能,实现对数据源、目的地的数据连贯对立治理治理,通过界面进行数据源与目的地注册,删除数据源,同时依据需要一直迭代反对新的数据库。 利用解析数据库归档日志的形式,零碎实现秒级的数据变更捕捉,将解析的变更记录传送到数据目的地中,包含日志中提取数据变更的增、删、改等DML操作记录,以及新增表、删除表、增加字段、删除字段等主动同步到目的地中 。 全域数据实时交融的价值愈发重要,是减速数据流通、从而晋升经营效率构建差异性竞争劣势的重要伎俩。该我的项目平台实现各零碎的买通与关联,笼罩多层次客户服务体系,强化了线上业务服务和资产配置等综合实力。该项目标施行晋升了几十家成员行的获客能力和精准个性化服务水平,助力成员行经营与治理数智化再降级。同时,简略易用的数据同步机制能够升高应答各种实时数据利用场景的老本,进步数据的复用度,高效开释数据价值。 山东城商行联盟数据库准实时数据采集零碎的施行是保持市场驱动和翻新驱动,充分发挥技术和数据因素价值的具体体现,在业界又创建一个数据管理榜样并造成了可复制教训。将来,联盟也将进一步施展全域数据管理根底平台劣势,以“赋能中小银行,简略金融科技”为使命,判若两人为金融机构提供全方位、高水平的信息科技服务。 点我理解DataPipeline更多信息并收费试用

December 24, 2021 · 1 min · jiezi

关于中间件:DataPipeline与飞腾完成产品兼容性互认证携手共建自主IT底层生态

近日,经严格测试,DataPipeline与飞腾顺利完成产品兼容性互认证。测试结果表明,DataPipeline实时数据交融产品在飞腾FT-2000+/64处理器平台上装置顺利、运行晦涩,单方兼容性良好。这是继鲲鹏、海光、兆芯后,DataPipeline适配的又一国内支流CPU产品,标记着DataPipeline在信创生态布局上的进一步欠缺。 “路漫漫其修远兮,吾将上下而求索。吾令凤鸟飞腾兮,继之以日夜。”自第一颗处理器研制成功开始,飞腾的技术演进已走过20余年的历史。飞腾是国内当先的自主外围芯片提供商,其产品具备谱系全、性能高、生态欠缺、自主化水平低等特点。基于飞腾CPU的产品波及多种类型的终端、服务器和工业管制嵌入式产品等,在国内云计算、大数据以及政务、金融、能源和轨道交通等行业信息系统畛域已实现批量大规模利用。 致力于成为“中国的世界级数据中间件厂商”,DataPipeline 通过自主研发的一系列实时数据技术帮助用户构建以业务指标为导向的数据链路,实现企业级实时数据管理指标。产品反对宽泛的数据节点类型,按需疾速定制、部署、执行数据工作,产品广泛应用于实时数据采集、数据订阅与散发、多云数据传输等场景。 目前,以信息技术利用翻新为代表的产业趋势已成为推动我国产业结构化降级的外围力量。实现信息技术畛域的自主可控和信息安全,在根底硬件、软件等畛域实现国产代替,已成为以后背景下国家和企业用户的独特诉求。国家在《十四五布局》中亦提出,要保持翻新驱动倒退,全面塑造倒退新劣势,同时放慢数字化倒退,建设数字中国。千行百业平安可信的数字化转型工作,势在必行。 DataPipeline积极响应国家“根底外围软件自主可控,打造世界一流软件强国”的号召,在信创倒退的浪潮中,保持自主翻新一直晋升产品竞争力,为数据的流通提供技术与平安保障,使客户可能将更多的精力付诸于数据利用翻新及更多价值畛域摸索,从而带来业务上的冲破。公司基于本身在实时数据管理畛域的深厚积攒,买通“实时数据交融-服务-品质”全流程能力,构建起业内最欠缺的实时数据管理产品矩阵,造成了全链路实时数据资产治理业务体系。飞腾是国内利用产品最为宽泛的头部芯片厂商之一,此次实现单方兼容性互认证,DataPipeline便可适配更多企业用户的IT利用需要,推动企业用户放慢数字化过程。同时,这将为进一步联通根底软硬件构建自主IT底层生态、优化信创生态布局、助力数字经济基础设施建设打下良好基础。 “连贯所有数据、利用和设施”,是DataPipeline的使命。目前,DataPipeline数见科技已与多家支流信创厂商实现产品适配优化,涵盖芯片、操作系统、数据库、大数据、云计算等多个畛域,兼容互认证产品包含华为鲲鹏920、海光、飞腾、兆芯、中科曙光H系列服务器、河汉麒麟、统信UOS、华为GaussDB、腾讯云TDSQL、巨杉SequoiaDB、TiDB、海量数据库、HashData、星环TDH、西方金信、青云等,满足相干行业高性能、高可用、高稳固、高可控等的能力诉求,可能无力反对重点畛域信息化程度当先的用户实现中间件平安可信。 点我理解DataPipeline更多信息并收费试用

December 20, 2021 · 1 min · jiezi

关于中间件:DataPipeline实时数据融合产品入驻青云云市场催化企业数据价值释放

近日,DataPipeline与青云科技达成单干,经单方严格联结测试与资质评审,DataPipeline企业级实时数据交融平台正式入驻青云云市场,将为泛滥企业用户提供数据全面精确、治理麻利智能、链路稳固高容错的实时数据管理服务,助力其突破技术壁垒,实现全域实时数据的价值开释。 DataPipeline实时数据交融产品入驻信息 青云QingCloud(股票代码688316)是国内技术当先的企业级云服务商与数字化转型解决方案提供商。青云云市场由青云倾生态全力打造,是为大中小微企业以及集体开发者提供软件应用及产品服务的交易和交付平台,聚合了根底软件、平安利用、人工智能、行业利用等不同畛域类别的优质服务商,为用户升高数字化老本,让用户可轻松查找、测试、购买与部署所需的利用和服务。 以后,新一轮科技和寰球产业改革一直推动,千行百业都在减速数字化转型。以金融为代表的信息化当先行业因服务场景繁多、数据量宏大、安全性要求极低等因素,成为改革过程中的排头兵。各机构踊跃通过无效的数据管理驱动经营模式更加智能。其中,构建残缺客户常识图谱实现精准营销、各管理层级间数据实时交互达成麻利协同、全生命周期智能风控等多样的业务场景,对数据获取的时效性要求越来越高。高效稳固的实时数据交融治理重要性显而易见。 DataPipeline提供企业级实时数据交融平台解决方案,通过基于日志的增量数据获取等多种实时数据技术,帮助客户构建以业务指标为导向的数据链路,按需疾速定制、部署、执行数据工作,反对从传统数据处理到实时数据利用的各类场景,齐全满足金融等行业高性能、高可用、高稳固、高可控等的能力诉求。该计划以“易建,好用,性优,平安”等个性取代用户自建等形式,成为银行、保险、证券、基金等泛滥行业用户落地实现的首选。产品现已服务了中国民生银行、中国人寿(海内)、山东城商行联盟、黑龙江省农村信用社、财通证券、国盛证券、山西证券、恒泰证券、财通证券资管、吉致汽车金融、长城汽车金融、尚诚生产金融等在各自行业信息化程度当先的用户。 基于此次单方单干,客户既能够抉择私有化部署形式,利用DataPipeline连贯自有环境与青云QingCloud,也能够间接在青云QingCloud利用市场中抉择DataPipeline提供的实时数据交融服务。DataPipeline实时数据交融产品与青云QingCloud底层资源深度交融,笼罩用户业务更多数据管理流程,产品力将取得充沛开释。 将来,单方还将在实时数据管理畛域开展更深层次的单干,将云计算、大数据、人工智能等技术进一步落地利用,为用户数据翻新业务顺利开展提供全方位保障。点我理解DataPipeline更多信息并收费试用

December 16, 2021 · 1 min · jiezi

关于中间件:朋友圈又添好友DataPipeline与统信服务器操作系统完成产品互认证

日前,DataPipeline企业级实时数据交融平台与统信软件旗下统信服务器操作系统V20实现产品互认证。DataPipeline正式成为统信软件产品生态搭档。本次认证基于鲲鹏、飞腾CPU平台,经严格兼容性及功能性测试,结果表明:DataPipeline产品在统信服务器操作系统上运行稳固、性能优异,可为用户提供平安高效的服务。 DataPipeline与统信产品互认证明 本次参加测试的DataPipeline企业级实时数据交融平台,通过自主研发的一系列实时数据技术帮助用户构建以业务指标为导向的数据链路,实现企业级实时数据管理指标。产品反对宽泛的数据节点类型,按需疾速定制、部署、执行数据工作,广泛应用于实时数据采集、数据订阅与散发、多云数据传输等场景。产品具备良好的生态适应性。此次产品兼容测试的顺利完成,将大大促成单方在金融、制作、能源、医疗、教育等各个行业的单干。 DataPipeline深知,产业数字化转型过程并非欲速不达,而是生态交融、产业协同的长期推动过程。其中,中间件在任何零碎建设中都起着承前启后、不可或缺的作用。作为企业面向信创转型降级的首选实时数据管理品牌,DataPipeline以助力数字经济平安持重倒退为主旨,继续进行生态布局及相干规范的建设推动工作。 继续生态建设,聚合产业资源DataPipeline产品不仅自身具备突出的平安个性,且目前已与多畛域重点信创厂商进行深刻适配优化,涵盖国内四大芯片厂商、重点服务器厂商、两大操作系统巨头、10+国内支流数据库厂商、头部云计算大数据服务商等,可能无力反对重点畛域信息化程度当先的用户实现中间件平安可信。其中,DataPipeline企业级实时数据交融平台已与华为GaussDB、巨杉SequoiaDB、TiDB、HashData、星环TDH等造成联结解决方案,服务于民生银行、中国人寿(海内)、中国石油、恒泰证券等客户利用场景,在“高平安、高性能、高稳固、高可用”等能力方面失去宽泛认可。 贯彻技术规范,推动规范建设随着云计算、大数据等技术的倒退,中间件软件产品状态越来越多,中间件标准规范的建设可为国内中间件研发、利用推广、保护提供更好的领导和参考。DataPipeline依靠齐全自主知识产权产品,深度参加国家标准制订与贯彻工作。 目前,DataPipeline企业级实时数据交融平台已通过中国信息通信研究院数据集成工具根底能力专项评测,历经“数据荡涤/转换、作业管理、平安保障”等共计6大部分、23个我的项目全面严格的技术考核。另外,DataPipeline参加了《中华人民共和国通信行业标准大数据消息中间件技术要求与测试方法》规范编制,并退出 “中国电子工业标准化技术协会信创工委会及其中间件工作组”、“北京信息化协会信创工委会”、“ 中国信息通信研究院CCSA TC601大数据技术标准推动委员会”参加组织内与数据中间件相干的规范制订工作。 将来,DataPipeline将以推动产业提高为己任,继续晋升产品创新能力和研发实力,同时借助政府和市场的政策机制,将获得的技术成绩、优良实际等重要资源与生态搭档串联并共享,以助力产业链买通、为各畛域的用户提供更优质的实时数据管理服务。点我理解DataPipeline更多信息并收费试用

December 13, 2021 · 1 min · jiezi

关于中间件:DataPipeline与TiDB推出异构数据实时同步解决方案共筑安全可信基础设施

近日,DataPipeline数见科技与PingCAP正式发表,通过联结测评单方已实现DataPipeline企业级实时数据交融平台与TiDB分布式数据库企业版联结解决方案的兼容认证,旨在为寰球客户在数据管理翻新方面发明更大价值。 DataPipeline & TiDB联结解决方案认证据悉,PingCAP自主研发的开源分布式关系型数据库TiDB,为企业要害业务打造,具备分布式强一致性事务、在线弹性程度扩大、故障自复原的高可用、跨数据中心多活等个性,目前已为1500余家企业服务,笼罩金融、运营商、制作、批发等多行业,与DataPipeline重点服务行业高度重合。 DataPipeline & TiDB联结解决方案架构DataPipeline与TiDB联结构建的异构数据实时同步解决方案以DataPipeline企业级实时数据交融平台为依靠,集成TiCDC(通过拉取TiKV变更日志实现的TiDB增量数据同步工具)的实时数据同步零碎,可无效解决异构数据库的相干数据处理、数据一致性保障等问题,反对金融行业外围业务零碎的准实时同步,满足各类简单实时数据利用场景。该计划采纳单次日志解析,多任务复用,防止反复日志解析;分布式解决,可无效晋升数据同步的即时性;反对反复解决/回滚等。 赛迪研究院在近日公布的金融数字化转型剖析报告中指出:以后,中国金融行业的数字化过程正在步入新的倒退阶段,从部分冲破走向全面发展,从通用畛域走向细分畛域,呈现出服务智能化、业务场景化、渠道一体化、平台凋谢化和交融深度化等特点。DataPipeline认为,该背景下,金融畛域数据时效性要求越来越高,在业务方面具体体现在“晋升集中度高且多样性的风险管理能力”、“注意力经济局势下进步互联网业务竞争力”、“从经营模式到晋升业务经营治理能力的转变”等。实时数据管理将成为下一代金融数字化翻新基础设施。同时,平安可信也是其能力要求的重中之重。 DataPipeline提供企业级实时数据交融平台解决方案,通过基于日志的增量数据获取等多种实时数据技术,帮助客户构建以业务指标为导向的数据链路,按需疾速定制、部署、执行数据工作,反对从传统数据处理到实时数据利用的各类场景,齐全满足金融行业高性能、高可用、高稳固、高可控等的能力诉求。 DataPipeline企业级实时数据交融平台,以“易建,好用,性优,平安”等个性取代用户自建等形式,成为银行、保险、证券、基金等泛滥行业用户落地实现的首选。产品现已服务了中国民生银行、中国人寿(海内)、山东城商行联盟、黑龙江省农村信用社、财通证券、国盛证券、山西证券、恒泰证券、财通证券资管、吉致汽车金融、长城汽车金融、尚诚生产金融、中国石油等在各自行业信息化程度当先的用户。 同时,为了给以金融为代表的国民支柱型行业提供平安可信的数据管理撑持,DataPipeline正在踊跃拥抱国产化布局,开展兼容适配助力欠缺信创产业链生态。据悉,DataPipeline目前已与多家支流信创厂商实现产品适配优化,涵盖芯片、服务器、操作系统、数据库、大数据、云计算等多个畛域,兼容互认证产品包含鲲鹏920、飞腾、海光、中科曙光、河汉麒麟、统信UOS、华为GaussDB、腾讯云TDSQL、巨杉SequoiaDB、TiDB、HashData、西方金信、星环TDH等,满足相干行业高性能、高可用、高稳固、高可控等的能力诉求,可能无力反对重点畛域信息化程度当先的用户实现中间件平安可信。点我理解DataPipeline更多信息并收费试用

December 10, 2021 · 1 min · jiezi

关于中间件:构建信创基础软硬件共同体DataPipeline与中科曙光完成产品兼容互认证

近日,DataPipeline数见科技与中科曙光独特发表,单方已实现DataPipeline企业级实时数据交融平台与中科曙光H系列服务器兼容性互认证工作。通过严格测试,单方产品兼容性良好,能够顺利装置、配置,零碎整体运行稳固晦涩且性能体现优异,可满足用户安全性、可靠性及关键性利用需要。中科曙光是中国信息产业领军企业,为中国及寰球用户提供翻新、高效、牢靠的IT产品、解决方案及服务。经验20余年倒退,中科曙光在高端计算、存储、平安、数据中心等畛域领有深厚的技术积淀和当先的市场份额,并充分发挥高端计算劣势,布局云计算、大数据、人工智能等畛域的技术研发,打造先进计算产业生态。 致力于“成为中国的世界级数据中间件厂商”,DataPipeline数见科技通过自主研发的一系列实时数据技术帮助用户构建以业务指标为导向的数据链路,实现企业级实时数据管理指标。产品广泛应用于实时数据采集、数据订阅与散发、多云数据传输等场景,为金融、通信、能源、批发及互联网等业务水平与信息化程度较高的客户提供平安可信的实时数据综合解决方案。 新一轮科技反动和产业改革正在减速,信息技术利用翻新产业已成为数字化转型、晋升产业链倒退的要害,也是当今中国数字经济平安倒退的基石。 对于DataPipeline数见科技与中科曙光来说,本次互认证是单方在国产根底软硬件信创产业生态倒退中迈出的新一步,更为产业转型降级、数字经济倒退提供了松软可信的新型基础设施。将来单方将以优质产品和技术单干为数字化、智能化社会建设提供更多源能源。 2006年,国务院公布《国家中长期迷信和技术倒退布局大纲(2006-2020)》将“核高基”(外围电子器件、高端通用芯片及根底软件产品)列为16个重大科技专项之一,标记着信创产业的起步。与传统信息技术产业相比,信创产业更加强调生态体系的打造。从全产业来看,构建基于我国自主IT架构的新生态还须要产业链各环节厂商的共同努力。 DataPipeline正一直深入信创生态布局。据悉,DataPipeline目前已与多家支流信创厂商实现产品适配优化,涵盖芯片、操作系统、数据库、大数据、云计算等多个畛域,兼容互认证产品包含鲲鹏920、飞腾、河汉麒麟、统信UOS、华为GaussDB、巨杉SequoiaDB、TiDB、HashData、西方金信、星环TDH等,满足相干行业高性能、高可用、高稳固、高可控等的能力诉求,可能无力反对重点畛域信息化程度当先的用户实现中间件平安可信。点我理解DataPipeline更多信息并收费试用

December 9, 2021 · 1 min · jiezi

关于中间件:和合共赢DataPipeline与麒麟软件完成产品兼容性互认证

近日,经屡次严格联结测试,DataPipeline与麒麟软件实现产品兼容性互认证。测试结果表明,DataPipeline企业级实时数据交融平台与河汉麒麟高级服务器操作系统(飞腾版)和河汉麒麟高级服务器操作系统(鲲鹏版)完满兼容,性能、可靠性等方面体现优异,可良好满足用户关键性利用需要。此次互认证将推动单方在金融等泛滥行业的单干力度,助力国产化生态体系的搭建,为保障数字时代中国数据资产的实质平安贡献力量。 “十四五”开局之年,中国全面进入科技自立自强的浩瀚征途,打造平安可信的核心技术成为重点。麒麟软件作为中国电子信息产业团体有限公司重要子公司,在国家要害信息基础设施建设中施展着中国操作系统主力军的作用。河汉麒麟高级服务器操作系统V10是针对企业级要害业务,适应虚拟化、云计算、大数据、工业互联网时代对主机系统可靠性、性能和实时性等需要,根据CMMI5级规范研制的提供内生实质平安、云原生反对、自主平台深刻优化的新一代自主服务器操作系统。在麒麟操作系统环境中,DataPipeline能够高效进行映射交融链路管理、构建数据链路,反对包含Oracle、IBM DB2、MySQL、Microsoft SQL Server及PostgreSQL等在内的数据库的实时增量数据捕捉,且性能优异。至此,DataPipeline的生态幅员又减少了“中国操作系统外围力量”这浓厚一笔。 DataPipeline 创始人 & CEO陈诚在2021公司新品发布会上谈道:“根底软件处于产业链上游,负责钻研、制订并管制软件产品的核心技术、体系结构和规范,管制着整个产业的游戏规则,是最容易被扼住喉咙的畛域。” 自成立以来,DataPipeline就以“成为中国的世界级数据中间件厂商”为愿景、以“切实加强根底软件根技术冲破”为己任。公司牢筑平安可信意识屏障,不断加强核心技术能力,不仅使客户掌握住数据的流动性,更把自主翻新倒退主动权紧紧抓在本人手中。 DataPipeline实时数据交融产品为企业级用户提供对立的平台,治理异构数据节点的实时同步与批量数据处理工作,采纳分布式集群化部署形式,可程度垂直线性扩大,保证数据流转稳固高效,让客户升高数据交融老本专一数据价值开释。通过多年在数据交融技术畛域的积攒,产品目前反对Oracle、MySQL、Microsoft SQL Server及PostgreSQL等数据库的实时增量数据捕捉,对大数据平台、国产数据库、云原生数据库、API及对象存储也提供宽泛的反对,并在一直扩大。产品齐全满足金融行业高性能、高可用、高稳固、高可控等的能力诉求,服务了民生银行、中国人寿(海内)、山东城商行联盟、财通证券、中国石油、吉利团体、星巴克、顺丰等在各自行业信息化程度当先的百余家客户。 DataPipeline 合伙人 & CPO陈雷示意:“信息技术翻新带来了生态变动,由此产生了新的技术挑战和产业时机。信创行业近年来的倒退,给DataPipeline带来了更多的开放市场空间和合作伙伴。DataPipeline由之前中间件产品与客户数字化环境的独自磨合,演进到能够在零碎层与相干合作伙伴进行组合式的适配及欠缺,以整体打包计划的模式进入用户的利用体系。以此为代表的单干状态,是国产软硬件在综合能力上的巨大进步,也是将来信创市场的竞争倒退方向。DataPipeline将继续以‘和合共赢’的凋谢理念、诚挚的态度,与包含麒麟软件在内的各个生态搭档进行深度交融,为用户带来更好的体验和效力晋升。” 局势挑战多变,产业同行方能致远。DataPipeline坚守“解答时代命题,不负时代担当”的初心,与全产业链搭档聚力推动生态交融共创产业凋敝倒退,在核心技术攻坚、信创产品兼容认证、要害行业利用示范等方面成绩硕然。目前,DataPipeline已与多家支流信创厂商实现产品适配优化,涵盖芯片、国产操作系统、数据库、大数据、云计算等多个畛域,兼容互认证产品包含鲲鹏920、河汉麒麟、统信UOS、华为GaussDB、巨杉SequoiaDB、TiDB、HashData、西方金信、星环TDH等,可能无力反对重点畛域信息化程度当先的用户实现中间件自主可控。往年,DataPipeline正式成为信创工委会会员单位(点此回顾),通过参加数据中间件相干的规范制订等工作,晋升产业协同与技术能力。 将来,DataPipeline将保持技术驱动、深耕企业服务,持续与国产软硬件合作伙伴一道,为金融等行业客户提供全链路实时数据资产治理解决方案,助力用户实现高质量数字化转型、以实时数据管理技术之光照亮自主翻新征程。

December 6, 2021 · 1 min · jiezi

关于中间件:首次统一调度系统规模化落地全面支撑阿里巴巴双-11-全业务

简介: 往年双 11 首次规模化亮相的对立调度,通过一套调度协定、一套零碎架构,对立治理底层的计算、存储、网络资源,超大规模、高效率、自动化的资源弹性,实现了业界新的冲破。在离线混部、离在线混部、新的快上快下技术,缩小数万台服务器洽购,带来数亿计的资源老本优化和大促效率晋升。 01 背景对立调度我的项目 1.0 胜利反对 2021 年双 11 大促,对立调度计划实现了从容器调度到快上快下全流程的全面降级和优化。项目组 100 多位核心成员,胜利走过了立项、POC、计划评审设计、关闭开发测试、大促冲刺各个阶段,历经考验胜利上线。 作为阿里巴巴的外围我的项目,阿里云(容器团队和大数据团队)联结阿里巴巴资源效力团队、蚂蚁容器编排团队,历时一年多研发和技术攻坚,实现了从“混部技术”到明天“对立调度技术”的全面降级。 明天,对立调度已实现阿里巴巴电商、搜推广、MaxCompute 大数据和蚂蚁业务的调度全面对立,实现了 pod 调度和 task 高性能调度的对立,实现了残缺的资源视图对立和调度协同,实现了多种简单业务状态的混部和利用率晋升,全面撑持了寰球数十个数据中心、数百万容器、数千万核的大规模资源调度。 云原生产品家族 02 对立调度技术全面降级云计算的实质,就是把小的计算碎片变成更大的资源池,充沛削峰填谷,提供极致的能效比。对数据中心低碳节能、绿色环保、科技倒退、更高效运行的谋求下,阿里巴巴对技术的摸索永无止境。阿里的技术人有一个现实,让数据中心的算力成为水、电、气一样的基础设施,开箱即用。 为了让业务间峰谷互补的劣势施展到最大,过来咱们构建了混部技术,突破多资源池的割裂,不同计算畛域的多调度大脑协同共用资源;老一代的混部技术带来了资源的对立和利用率的微小晋升,但多调度器的实质让咱们的谋求受限。 阿里巴巴继续谋求构建可撑持更多简单工作无差别混部、极致弹性互补、当先的新一代调度技术,实现极致的全局最优调度,提供更高质量的算力。往年咱们在技术上达到一个新的临界点,容器服务 ACK 牵头并协同泛滥团队,启动了基于 ACK 的新一代对立调度我的项目。 容器产品家族 往年双 11 首次规模化亮相的对立调度,通过一套调度协定、一套零碎架构,对立治理底层的计算、存储、网络资源,超大规模、高效率、自动化的资源弹性,实现了业界新的冲破。在离线混部、离在线混部、新的快上快下技术,缩小数万台服务器洽购,带来数亿计的资源老本优化和大促效率晋升。 往年首次引入大规模数据智能来进一步丰盛调度能力,提供了包含实时的负载感知,主动规格举荐(VPA),差异化 SLO 工作负载编排,CPU 归一化,反对周期性预测的 HPA,分时复用等,提供了更多维度的老本优化技术和高牢靠的容器运行时保障。 围绕着新一代的对立调度,阿里巴巴电商、搜寻、大数据等泛滥平台、不同类型的简单计算资源都以统一的形式申请资源,兼顾的额度治理和资源布局,数十万核资源借用秒级即可实现。基于对立调度,阿里云与蚂蚁也实现了调度技术交融,蚂蚁生态全面降级为对立调度。调度平台为将来带来更多设想空间,例如,咱们能够通过泛滥伎俩,例如价格杠杆等经济因素,驱动阿里外部的业务更正当应用各个数据中心的资源,确保数据中心全局资源水位尽可能均衡,以改良数据中心的能效比。 阿里云容器服务 ACK 对规范 Kubernetes 进一步加强,更高性能吞吐和更低的响应提早构建稳固牢靠的超大规模单集群能力,安稳撑持了 1.2 万节点超 100 万核的超大规模集群、为对立调度大资源池化的生产运行提供了松软的基座。阿里巴巴泛滥类型的简单资源也实现了基于容器服务底座 ACK 的全面交融降级。 除电商、搜寻、大数据等阿里经典场景外,对立调度也极大的赋能了新型的技术创新。以直播电商场景为例,决策对实时计算的需要很高,比方薇娅双 11 直播间 9 千多万在线观看人数的产生的浏览、交易等实时数据的秒级数据分析。往年阿里将实时计算引擎 Blink 降级为基于对立调度的新一代引擎,在老本、性能、稳定性以及用户体验上取得大幅提高,大规模作业拉起性能相比 Yarn 提速 40%,谬误复原效率晋升 100%,通过对立调度技术在双 11 大促备战接节俭数十万 CPU,在集群 CPU 水位超过 65% 时,实现全局零热点,保障了各直播推流的时效性。 ...

November 19, 2021 · 1 min · jiezi

关于中间件:MQ是什么Q

1. MQ是什么?MQ是Message Queue,音讯队列。队列是一种FIFO先进先出的数据结构,音讯队列就是寄存音讯的队列。音讯由生产者发送到MQ进行排队,而后由消费者对音讯进行解决。设想一下,你正在公司改bug,领导通知你这个问题明天必须搞定。而这个时候,你的快递到了,快递小哥疯狂地给你打电话让你去取时,你会怎么做?“帮我放在菜鸟驿站吧,谢谢!” 在上边的例子中,“快递” 就是音讯,“菜鸟驿站” 就是MQ。 2. MQ有啥用?1. 异步有了菜鸟驿站之后,快递小哥不必等着你去取快递,你也随时能够去菜鸟驿站拿了,单方的效率都失去了进步。 咱们晓得异步能进步零碎的响应速度和吞吐量,然而却不好实现,须要思考很多货色。而引入MQ就能够很不便的帮咱们的零碎实现异步解决,从而进步零碎的性能。2. 解耦快递小哥把快递放到菜鸟驿站后,就能够去送下一个快递了,并不必依赖你什么时候才去取而你也不必管到底是哪个快递小哥给你送来的,你只须要去菜鸟驿站拿就行了。 音讯队列也是一样,MQ能够对服务之间进行解耦,缩小服务之间的影响从而进步零碎的稳定性和可拓展性。3. 削峰你双11剁手买买买了一堆货色之后,过了几天快递小哥忽然给你送来一大堆快递,让你一次性把他们都抗回家去,你也会像忽然收到一大堆音讯的服务一样解体吧,不如让他把所有的快递都先放到菜鸟驿站,你一个一个再去取。 MQ能够以稳固的系统资源应答突发的流量冲击,从而避免服务的解体。3. MQ有啥毛病?1. 零碎复杂度进步,引入了MQ,必定零碎架构会变得比之前简单如何保障音讯不失落?如何保障音讯不会反复调用?如何保障音讯的程序?2. 零碎可用性升高,因为一旦MQ宕机了,整个零碎都会受到影响3. 数据一致性问题比方A零碎发消息,须要B、C两个零碎一起解决,如果B胜利而C失败了,应该怎么办? 引入了MQ,这些问题都须要进行额定的思考,所以不是所有的零碎都适宜应用MQ。

November 18, 2021 · 1 min · jiezi

关于中间件:EDAS-40-助力企业一站式实现微服务架构转型与-K8s-容器化升级

简介: EDAS 正式来到 4.0 时代,公布多项重磅新能力;同时联结新产品—云原生利用设计开发平台 ADD 1.0,一起公布云原生利用研发&运维 PaaS 产品家族,助力企业应用架构现代化降级。 作者:安绍飞 前言近年来,企业的数字化随着互联网的遍及倒退越来越快,技术架构也是几经更迭,尤其是在线业务局部。最开始企业的需要就是将业务尽可能在线化、线上化,产生了晚期的在线业务利用架构,即单体利用,次要就是由 Web 利用中减少业务逻辑及后端数据存在数据库。 随着在线业务的减少,以及更多的拜访增长,发现单体利用曾经支撑不了业务了,进而逐渐演进到分布式应用。同时,前端加上了负载平衡来承接日渐增长的申请,两头也引入了更多音讯、缓存等中间件和数据库。 随着云计算的倒退演进到云原生时代,企业的利用也开始面向云进行容器化、微服务化的构建,在这个过程中,就带来了和之前阶段不同的变动,形象来看次要是利用的开发设计、利用交付、线上运维方面的变动。image.gif 云原生应用服务的新诉求在云原生利用日益成为支流的技术架构下,云原生利用如何更好的利用云服务,实现面向云服务的架构设计、让业务更麻利的研发,疾速的联调验证就尤为重要。这就要求平台能够提供一站式的 PaaS 产品来进行撑持。 1)首先是开发设计:从原来的层次化/模块化单体架构,演进到全面的微服务化,应用 SpringCloud、Dubbo、Servicemesh 这一些技术栈来构建微服务,那这个过程中,研发人员须要进行面向微服务的架构设计、测试人员须要面向微服务架构设计测试用例,编写实现自动化测试、同时随着环境上云,也要求着开发环境与云端环境可能实现联通调试。 2)接着是利用交付:从之前的虚拟机&批量脚本来实现部署交付,到通过容器、K8s 等技术实现通用的标准化交付,这个过程中,也呈现了一些新的需要,比方批量的通过利用模板来疾速部署交付、以及通过利用跨集群来实现多场景的治理交付。 3)第三局部是线上运维的变动:从原来的虚拟机维度运维,演进到容器集群维度的运维,须要有更高的视角来帮忙企业的开发运维同学,这里咱们提出鸟瞰式运维理念,通过利用视角鸟瞰 K8s 所有资源,运维治理的不再是独自针对 Deployment、Service、Ingress 这些 K8s 原子资源进行,而是鸟瞰式的对立监管控实现运维。 EDAS 4.0 全面降级 &ADD 1.0 重磅公布针对下面提到的生命周期三个阶段新场景演进产生的新诉求,EDAS 正式公布了 4.0 版本,新增多集群利用治理、微服务 API 治理与测试、端云联调 3.0 等新能力。同时重磅公布新产品 --- 云原生利用开发设计平台 ADD v1.0,大大晋升云原生利用的开发效率。 接下来将为大家逐个具体介绍。 云原生利用设计开发平台 ADD 1.0公布针对开发设计阶段的需要,云原生利用设计开发平台 ADD 这个产品应运而生。ADD 产品的设计初衷就是为了晋升企业在云原生利用开发设计阶段的工作效率,进步生产力。它有 6 大特色: 可视化利用架构设计:帮忙企业不便的积淀与保护原来在线下白板上的架构探讨设计; 前端网页利用拖、拉、拽设计:实现前端“无代码”开发; 后端代码在线开发与调试:保障代码平安; 一站式集成面向接口的测试用例治理与自动化执行配置能力:实现在线自动化测试; 集成支流项目管理工具:进步云原生化开发项目管理效率; 业务利用组件高效复用:借助利用组件商店,实现全面的资产复用; EDAS 4.0 全新降级——微服务 API 治理与测试在微服务化的过程场景里,咱们总结出这样三个挑战: ...

November 17, 2021 · 1 min · jiezi

关于中间件:分布式-DBLE-的-general-日志实现

作者:文韵涵 爱可生 DBLE 团队开发成员,次要负责 DBLE 需要开发,故障排查和社区问题解答。 本文起源:原创投稿 *爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。 问题背景在应用某些 GUI 工具连贯 DBLE 操作时,会因为某些 SQL 在 DBLE 中不兼容导致 GUI 工具出现异常不能失常应用。 通常排查计划: 步骤一:须要晓得 GUI 工具操作时下发了哪些 SQL 至 DBLE ;个别用 tcpdump 、Wireshark 等抓包工具获取 SQLs步骤二:将 SQLs 一一在 Mysql Client 中执行,定位问题 SQL排查案例1登陆 phpMyAdmin 首个界面,未展现数据库列表 GUI 工具: phpMyAdmin 7.4.20 (这里用的是docker) DBLE 版本:3.21.02.x ##docker形式搭建phpMyAdmin## 拉取phpmyadmin镜像$ docker pull phpmyadmin/phpmyadmin ##初始化phpmyadmin容器 且关联dble服务$ docker run -d --name myadmin_aliyun -e PMA_HOST=xxx.mysql.rds.aliyuncs.com -e PMA_PORT=3xx6 -p 8081:80 phpmyadmin/phpmyadmin ##详解:-d:当前台模式运行--name myadmin: 容器命名为 myadmin, 容器治理时用(启动/进行/重启/查看日志等)-e PMA_HOST=xx.xxx.xx.xx: Dble服务器域名或IP地址-e PMA_PORT=8066: Dble的8066端口-p 8080:80: 端口映射, 本地端口:容器端口, 拜访: http://ip:8080phpmyadmin/phpmyadmin: 要初始化的镜像名拜访 http://ip:8080 ,应用 DBLE 的 8066 用户明码登陆;登入后的界面发现未展现数据库列表,如下图: ...

September 23, 2021 · 2 min · jiezi

关于中间件:技术人生解决问题的规律

简介:本文将介绍问题钻研背景及解决问题的个别法则和非凡法则及二者之间的辩证关系。作者:贺迷信 往期技术一号位方法论系列文章: 「技术人生」专题第1篇:什么是技术一号位? 「技术人生」第2篇:学会剖析事物的实质 一、背景1. 从事物的实质说起事物本质就是外部的主要矛盾次要矛盾的演变过程,同时该演变过程受外界环境其余事物的互相关联和相互影响。在广泛的状况下,一个事物的生命周期,是它的主要矛盾、次要矛盾被解决的过程体现。如何剖析问题实质,咱们曾经在《技术一号位的方法论【实践篇】—— 事物本质剖析的操作步骤及剖析事物本质的必要性》一文中给出了剖析过程和模板,感兴趣的同学能够应用这个模板疏导本人剖析本人的业务。 咱们日常生活、工作中遇到问题都是先从主要矛盾动手,解决了主要矛盾、次要矛盾,随着事物倒退到新的阶段,新的主次矛盾也会持续呈现。当然新的主次矛盾并非凭空出现,而是过来的其余矛盾演变而来,在事物以后生命周期所处阶段,在问题所处的范畴内,成为了妨碍事物持续倒退的主要矛盾次要矛盾。这就形成了事物的倒退过程,事物的倒退过程恪守了这一法则。 如上图所示,当咱们面对复杂事物时,最开始只能感知到以后事物和本人关联最严密的某个方面,即该事物的某个维度。从这个维度动手,解决最外围的问题,即主要矛盾。随着精力和资源的一直投入,当主要矛盾的次要方面、次要方面被逐渐解决,新的主要矛盾呈现,事物倒退会进入下一阶段,如下图所示,事物在某一维度上的纵向倒退,实际上就是一个问题的粒度一直细化的过程,也是生产力对事物的革新不断深入的过程。这一点通知咱们,须要深刻地而不是外表地看问题。 而当事物纵向倒退的同时,随着纵向问题的一直解决,横向的新的维度也会逐渐成为该复杂事物的主要矛盾次要矛盾,如下图所示,事物在横向发展上被感知和解决的维度变多,人们对事物的认知从繁多维度向多维度转变。这个过程通知咱们,须要全面地而不是全面的看问题。 当咱们看到了事物在某一个维度上的纵向倒退的过程,以及事物在多个维度上的横向发展的过程之后,要意识到这两个过程并不是某个过程先于另外一个过程产生的,更多是同时产生的,两个过程的联合并且一直演进各自的倒退过程才是事物自身倒退的法则,最终咱们能够从下图看到一个事物通过若干个阶段的倒退造成的全貌。这一点通知咱们,须要系统地而不是零散地看问题,同时还要以倒退的眼光看问题,而不能动态地看问题。 以上的内容都是围绕事物外在来看它的倒退过程的,联合事物本质的剖析一文来做剖析,咱们还须要看到事外部环境中的其余事物与以后事物的互相关联和相互影响。这一点也通知咱们,要广泛分割地而不是繁多孤立地看问题。 综合后面的图示和阐明来看,深刻地看问题,就是要看到事物倒退过程的细节,各维度下的畛域的细节,这是宏观的视角;全面地看问题,就是要看到更多维度,是宏观的视角;这个过程实际上是从宏观到宏观的视角切换的过程。 要系统化地看问题而不是零散地看问题,就是在视角从宏观切换到宏观的过程中,关注点要从部分切换到整体,从而以全局视角来对待问题; 要广泛分割地而不是繁多全面地看问题,就是要看到外部环境与事物外部主次矛盾的关系和相互影响,既向内看到本身外部的决定性因素,又向外辩证地对待环境对内的影响以及外在对外在的影响和反馈。这个过程其实就是从外向外的视角切换的过程。 要以倒退地眼光看问题而不是动态地看问题,就是不管在以宏观视角还是以宏观视角看问题时,都须要同时在工夫维度上看这个问题的过来是什么样的、当初是什么样、过来是如何演变为当初的、将来可能会变成什么样; 面对简单的问题时,咱们只有从这些角度理清问题的实质,能力在解决问题时,抓住实质和重点。 所以解决问题的过程其实就是:问题的解决由主到次,由骨干到细节,随着该过程的一直迭代,须要被解决的粒度变细,问题须要被解决的维度变多。失常状况下,所有的问题的解决,都合乎这个法则,体现了解决问题的形式的普遍性。 2. 什么是法则在探讨事物的实质的时候,咱们提到了事物倒退是听从一个法则的,然而理解法则对于理论解决问题有什么用途?技术一号位为什么要理解解决问题的法则?做技术和做业务有什么法则可循么? 在答复这些问题之前,咱们首先要一起看下到底什么是法则,马克思主义哲学的角度是怎么剖析法则的,法则具备哪些个性。以下内容全副皆为从《马克思主义哲学原理》(陈先达、杨耕著) 教材中摘抄的要害内容,受限于文章篇幅,局部内容应用省略号省略,比拟关注的读者能够查看原文来更加全面、系统地了解什么是法则: 法则是实质的、必然的和稳固的分割法则的外延首先法则是事物及其倒退过程中的实质的分割。事物之间存在着广泛的分割,但并不是所有的分割都是实质分割,都形成法则。…… 这就是说,法则不是事物的景象,而是属于事物本质档次的货色;法则不是通过感官能够间接把握的,规律性的意识属于感性思维档次的意识。 其次,法则是事物及其倒退过程中的必然的分割。法则和必然是等同水平的概念,代表着事物倒退过程中必然如此,确定不移的趋势。所谓法则的偶然性,就是指法则的存在、法则的作用及其结果的不可避免性。具体来说,一些事物的存在,不可避免地会引起另一些事物的呈现;事物倒退的这一阶段,不可避免地要把事物疏导到另一阶段。…… 在事实中,法则的偶然性并不意味着法则只有一种表现形式,也不意味着法则只能以一种形式实现进去。在了解法则的偶然性时,要留神把法则的偶然性与法则的实现形式做适当的区别。 最初,法则是事物及其倒退过程中的稳固的分割。所谓稳固的分割,是指只有具备肯定的条件,法则就会重复起作用,广泛地实现进去。法则的偶然性正是在法则的重复性、普遍性中得以体现的。…… 因而法则的重复性是在一个一个不可反复的事物中体现进去,法则的重复性只是反复贯通同类事物中的偶然性的内容。用事物的不可重复性来否定法则的重复性,实际上是混同了法则的重复性与事物的重复性的区别。 法则的实质不是全演绎,而是对事物本质的把握。在个别之中存在个别,无限之中蕴含着有限。在肯定的事物或流动中证实了规律性,也就是在有限的同类事物中证实了法则的重复性。 任何法则都是主观的,不以人们的用意和欲望而存在并产生作用,既不能人为发明,也不能人为毁灭。法则既不能人为发明也不能人为毁灭,并不意味着在历史上产生作用的所有法则都永远起作用。 任何法则都是在肯定条件下起作用的(这句话极其重要,是本文前面探讨个别法则和非凡法则的转换过程的根底)。法则既不能人为发明也不能人为覆灭,也不意味着人在法则背后无能为力。人们能够通过扭转、发明法则产生作用的具体的条件而扭转法则产生作用的模式。 法则的类型依据法则存在畛域的不同,能够把法则划分为自然规律、历史法则和思维法则。 依据法则发挥作用范畴的不同,能够把法则划分为个别法则和非凡法则。所谓个别法则,就是对肯定畛域内所有事物都起作用,对倒退的全过程都起作用的法则。非凡法则则是对该畛域内某些事物起作用,对该倒退过程的某些阶段起作用的法则。 个别法则和非凡法则之所以有作用范畴大小的区别,本源在于个别法则和非凡法则产生作用所须要的条件不同。一般来说,在肯定质的零碎中,个别法则之所以能对该零碎所有的事物及其倒退的全过程都起作用,是因为个别法则产生作用所须要的条件比拟个别,比拟少,而非凡法则产生作用所须要的条件比个别法则产生作用所须要的条件更多,更具体。 从法则产生作用的条件看,法则的普遍性共同性水平是通法则产生作用所须要条件的数量成反比的。法则作用的普遍性水平越高,它发挥作用所须要的条件越少;法则作用的普遍性水平越低,它发挥作用所须要的条件就越多。 对立统一法则是辩证法的本质和外围 (该局部内容与本文主题无关,仅用于科普的目标放进去)唯物辩证法的法则体系就是由 对立统一法则、质变量变法则和否定之否定法则这三个基本规律,以及内容与模式、实质与景象、起因与后果、必然与偶尔、事实与可能等一系列领域所形成的。其中,对立统一法则形成了辩证法的本质和外围。 3. 为什么要钻研法则钻研法则的目标,是为了迷信地、捕风捉影地、正确地解决日常生产生存中遇到的问题,防止因为不合乎客观规律而带来损失。在日常工作中,往往会遇到看起来非常复杂的场面,如果咱们不把问题剖析分明,不寻找暗藏在问题景象背地的法则,在解决问题的过程中生吞活剥过来的一些教训或者书本上的常识,那么就很可能会呈现经验主义,也会呈现实践偏离理论的教条主义。教训也好,常识也罢,都须要基于事实为根底,不违反事物倒退的客观规律,否则就会被法则反过来教训,付出额定的代价。所以钻研法则有益于止损。简而言之,人们能够“通过做事符合规律”来躲避失败的危险。 钻研法则的目标,是为了找出问题所合乎的法则,而后联合法则产生作用所须要的条件,通过肯定的生产力伎俩来发明该条件,从而利用法则的发展趋势来疏导事物的倒退从而达到咱们冀望的目标。在日常工作中,特地是做业务,对于技术一号位而言,如果只能埋头做本人手中的需要,而不理解业务倒退的法则,那么就无奈在适当的工夫投入适当的兵力做适当的事件。这种状况下,技术一号位实际上变成了仅仅带着一个团队做需要的“包工头”,而不是能够帮助业务一号位实现推动业务倒退重任的技术一号位。 在之前的文章中咱们提到过技术一号位的职责是什么,其中,在零碎架构方面,零碎架构的前瞻性、可扩展性的前提就是可能把握业务倒退法则而提前做了技术架构上的布局;除此之外,在兵力的投入、战斗的发动等组织协同方面也都须要合乎业务倒退法则。如果不论业务以后阶段的问题和主次矛盾,也不论这个主次矛盾将来会朝什么方向倒退,那么最终技术只能被动地响应业务需要,被业务需要推动倒退。 如果提需要的人把握了业务倒退法则还好,一旦提需要的人眼里也只能看到客户抛出来的问题而不是业务发展趋势和法则,那么可想而知技术的投入本质上是在围绕着细枝末节做无用功。而对于那些有能力的技术一号位,做的各种技术决策不仅能撑持业务的倒退,保障业务的运行,更重要的是利用生产力的晋升,联合业务倒退的法则来疏导、驱动业务的倒退。咱们明天不聊具体某个事件怎么做,如果有同学想探讨个例,咱们能够线下交换。须要大家明确的是,每个业务所处环境不一样,每个业务所处的倒退阶段不一样,所以讲再多的个例都没有意义。咱们要间接从不同个例中的共性讲起,讲透,找到法则,这样就能让更多的人做业务的时候晓得当初要做什么,为什么要这样做,接下来要做什么。简而言之,就是通过“预测事物倒退法则”,依附法则来从事物倒退中获益。 钻研法则的目标,也是为了利用个别法则和非凡法则的辩证关系,把握突破法则的能力,从而让看起来不可能、不符合规律的事件产生,从而从中受害。“看起来不可能、不符合规律”的事件,可能是减速事物某个阶段的倒退,也可能是间接跳过事物的某个倒退阶段间接进入下一阶段,还可能是缩短了某个事物在某个阶段的停留。总之,在结构性上影响事物的倒退,要比单纯地利用法则或抗拒法则获益更大,当然影响也更粗浅。 比方做业务的过程中,咱们能够利用已有的中间件和零碎服务来升高业务启动过程中的技术投入从而减速业务启动过程;咱们能够利用已有的根底保障机制和零碎工具来升高业务倒退过程中的系统性危险,从而可能把兵力聚焦在业务问题的解决上,从而可能跳过反复的稳定性建设的阶段,减速业务倒退过程;原来一个业务要必然经验的生命周期的各个阶段,都随着相干技术的复用和生产力的晋升而在工夫上被压缩或间接跳过,因而业务倒退速度要比单纯堆人力要更快。 所以“业务倒退恪守其生命周期”这一非凡法则,被突破的时候,就能让业务跳过某些看起来是必须的无奈跳过的环节。简而言之,就是通过“突破法则”,来发明看起来的不可能。 咱们须要辩证地了解“看起来不可能”。看起来不可能本质上是产生了“在某人或某些群体认知之外的” 的事件,在具备更高的生产力的群体来看,前者眼里的不可能大概率是稀松平时的事件,举个简略的例子:飞机对于原始部落和现代文明而言,别离是“不可能”和“平常事”,实质上问题不在于飞机,而在于不同群体所把握的生产力的差别。对于认为“不可能”的群体,让他们突破既有认知法则的最简略的形式就是把更先进的跨代的生产力赋予对方。 二、解决问题的个别法则和非凡法则及二者之间的辩证关系1. 为什么要剖析解决问题的法则咱们日常生产生存中,很多事件,最初实质上都能够形象为在解决问题,只不过问题所属的畛域不同,背景不同,波及的方面不同,问题所处的环境和倒退阶段也不同,尽管变幻无穷,即事物自身存在特殊性,然而在如何解决问题上,也是有个别法则和非凡法则存在的,也是合乎矛盾的普遍性的。因而把解决问题的法则钻研分明,剖析分明解决问题的个别法则和非凡法则之间的辩证关系,对咱们日常工作和生存有极大的益处,或者说,对于技术一号位来讲,有助于做好日常工作,履行好角色赋予的职责。 2. 为什么要剖析个别法则和非凡法则之间的辩证关系在下面的剖析中咱们能够看到,钻研法则的最高境界是突破法则,而突破法则须要了解个别法则和非凡法则之间的辩证关系。 如果只是单纯地、抽象地探讨这个个别法则,那么对于咱们理论生产生存中解决问题的指导意义太弱,而如果不探讨这个解决问题的最根本的个别法则,那么再探讨更具体的场景时,非凡的法则是如何来的,非凡法则如何被突破,就说不清了。所以二者之间的辩证关系是咱们最高效地利用法则的实践根底。 咱们上文中援用了《马克思主义哲学原理》教材中的一段话,这段话是对于个别法则和非凡法则的关系的。然而从探讨能够看出,教材只简略地提到了个别法则和非凡法则的差异,并没有探讨二者之间的关联性。在这里咱们尝试来剖析一下二者之间的关联性,剖析分明二者之间的辩证关系,从而可能让咱们从中获益,疏导咱们看清在日常做业务、做技术的过程中,看明确个别法则是什么,非凡法则是什么,如何利用个别法则来“突破”非凡法则,或者利用非凡法则来突破个别法则,从而可能让事物倒退的过程受咱们的疏导。 “突破法则”看起来和“做事件要合乎客观规律”是矛盾的,但“突破法则”本质是指扭转事物符合规律的条件,从而让事物合乎新的法则;而“做事件要合乎客观规律”讲的是事物所属环境的条件不论怎么变,都是会听从某一种法则的。因而实质上二者并不矛盾,要辩证地了解这个“突破法则”和“做事件符合规律”的关系。 3. 个别法则和非凡法则之间的辩证关系在接下来的探讨中,咱们会把法则对事物起的作用简化表述为“管制”。这并非学术性的简化,只是单纯为了精简探讨过程,并且把表述口语化。 个别法则和非凡法则之间的辩证关系具体如下: 在肯定畛域内,个别法则对所有事物起作用,包含该畛域内的合乎某个非凡法则的事物。在肯定畛域内,非凡法则管制的事物对外体现为受非凡法则的管制,然而并不意味着个别法则所起的作用不存在。在肯定畛域内,非凡法则和个别法则是叠加存在独特施展着作用的,在非凡法则的条件下事物沿着非凡法则的解放倒退,当满足非凡法则的条件隐没时,事物整体的倒退受个别法则管制。在肯定畛域内,“构建合乎非凡法则的条件”是决定事物受非凡法则管制还是受个别法则管制的关键因素,而生产力是决定该关键因素的关键因素。对于个别法则和非凡法则,咱们能够从如上示意图中看到,个别法则的影响范畴大,普遍性高;非凡法则的影响范畴小,普遍性低而特殊性高;同时,非凡法则须要更高的生产力,而个别法则则对生产力的要求不高。同时咱们须要晓得生产力的利用会带来老本,所以个别法则和非凡法则之间的转换也会波及到老本因素,如下图所示: 基于下面的剖析以及示意图能够晓得如下论断:事物受非凡法则影响还是受个别法则影响是能够互相转换的,而让这种转换产生的要害是对该事物操控的生产力的程度。生产力低下的时候,事物在个别法则或者非凡法则之间转换的难度高,事物在所处环境和条件下更偏向于恪守使之产生的法则而不产生所恪守的法则的变动;生产力进步的时候,事物在个别法则或非凡法则之间转换难度随着生产力的进步而变低,事物恪守的法则能够在生产力的帮忙下调整从而容许人间接影响事物倒退法则。 因而,当咱们想要利用法则甚至突破法则的时候,咱们能够持续从下面的实践剖析得出如下论断: 1. 在咱们生产力程度比拟低的时候,解决问题要合乎事物的倒退法则; 2. 而在生产力程度比拟高的时候,咱们能够通过调整事物合乎非凡法则的条件从而让事物恪守非凡的法则,或者让事物不再恪守非凡法则而回归个别法则的管制; 3. 如果咱们想要突破法则让看似不可能的事件产生时,不是仅仅把资源投在事件的自身上,而是同时须要投入在与之相干的生产力的晋升上,二者之间的投入比例须要视理论状况做调整。 4. 解决问题的个别法则和非凡法则探讨完个别法则和非凡法则的辩证关系,咱们终于能够探讨解决问题的个别法则和非凡法则了。 ...

June 2, 2021 · 1 min · jiezi

关于中间件:分布式-如何为-DBLE-贡献源码中间件开发需要掌握的技能都有什么

作者:路路 酷爱技术、乐于分享的技术人,目前次要从事数据库相干技术的钻研。不定时更新集体公众号WU双。 本文起源:原创投稿 *爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。 前言一个好的开源产品,首先须要有一个成熟稳固的版本,其次须要有一个沉闷的社区。成熟稳固的软件可能吸引用户应用,从而构建产品的社区,社区反过来也可能促成产品的进一步倒退欠缺。 所以说,产品与社区是相互作用,相辅相成的关系。 明天想为大家介绍下中间件开发所需的技能,说不定可能吸引对中间件开发感兴趣的同学,进而成为DBLE的源码贡献者呢。 本文首先介绍中间件开发所需的通用技能,这些技能不光光是DBLE开发所须要的,而是所有中间件开发都须要的通用技能。而后更进一步,介绍数据库中间件开发所需的非凡技能,这些技能可能与其余中间件开发技能有所不同。 中间件开发所需的通用技能中间件是一种独立的系统软件服务程序,对上服务于具体的利用,常见的中间件有数据库中间件、消息中间件、缓存中间件等。 中间件开发对于技术的要求能够说还算是较高的,以下是我总结的中间件开发所需的比拟重要的技术。 1、 多线程 多线程技术是中间件开发所必须把握的核心技术之一,起因在于其对性能的晋升作用。 多线程可能充分利用多核CPU的性能,从而进步零碎的吞吐量,而线程池技术又可能缩小线程创立及销毁的开销,从而更进一步晋升零碎的性能。 当然多线程也同样带来了一些问题,可见性、有序性、活跃性,这些都是多线程技术带来的问题,也有人说性能的晋升是他能够忍耐多线程带来这些问题的惟一理由。 无论如何,多线程技术都是中间件开发所必须的技能。当然多线程技术的学习也不是那么的容易,不要置信网上所说的什么一篇文章精通多线程这些内容,永远没有一篇文章能让你精通多线程,常识的学习没有捷径。 对于JAVA的多线程学习,我举荐《JAVA并发编程实际》,毕竟作者都是JCP的专家组成员,另外JAVA程序员能够通过残缺的浏览JUC源码包来学习多线程。 2、 网络编程 网络编程对于中间件的开发而言,也能够说是最重要的技术之一了。 网络连接的建设及网络数据包的读写、网络协议的解决,是中间件的根底也是难点。当然当初有一些网络框架比方Netty可能帮咱们很好的解决这些问题,但对于中间件开发者而言,对网络编程还是越相熟越好,这样在面对一些网络问题的时候,咱们也可能不慌不乱,知其然知其所以然的底气,在这时应该可能很好的体现进去。 对于DBLE的网络解决,我之前写过一系列的源码解读文章,DBLE的网络模块都是用JDK原生IO包实现的,通读一遍应该能够帮忙大家大略理解网络编程。 3、 设计模式 中间件不同于业务开发,不能一遇到新需要就简略的加代码加逻辑进行解决,而是要从整体架构角度思考,必要时还须要重构现有模块,以便增加新的性能扩大。 所以对于中间件开发,就须要咱们把握各类设计模式,同时也须要把握重构相干的技能。 设计模式举荐《设计模式:可复用面向对象软件根底》这本书,重构技能举荐《重构:改善既有代码的设计》这本书。同样,常识的学习没有捷径,还是须要你急躁读完,另外通过实际去了解,能力有所把握。 4、 异步编程 高性能框架个别都有很多的异步逻辑,通过异步回调来实现流程管制。异步编程在取得高性能的同时,也失去了肯定的可读性,因为代码的逻辑可能被碎片化了。但对于高性能利用来讲,异步编程也是须要去学习的。 5、 算法及数据结构 算法及数据结构是计算机的基础学科,所以对于中间件来讲,天然也离不开它们。 6、 测试 如何保障产品的品质,除了软件开发流程的标准化,代码review等,测试能够说是最重要的一环了。 测试有最根本的单元测试、集成测试,还有性能测试,疲劳测试等。对于中间件开发人员来说,这些都是须要把握的测试技能。 7、性能调优 决定零碎性能瓶颈的是零碎中的串行局部,以及与内部零碎的交互局部。性能调优的第一步是定位出零碎的性能瓶颈点,这当然须要你对系统有很深的了解,同样也须要度量工具的辅助。 性能调优的思路包含将串行工作并行化,工作异步化等。 以上是集体认为的中间件开发所须要的通用技能,可能不肯定很全,但最根底最重要的内容应该都包含了。 数据库中间件开发所需的非凡技能数据库中间件与中间件比照多了哪几个关键字,答复是“数据库”。所以数据库中间件开发所需的非凡技能,其实是与数据库技术相干的技能。 实际上,对于数据库中间件开发人员来讲,越往后越会发现自己离数据库越来越近。 数据库中间件开发所需的非凡技能如下。 1、 SQL 数据库中间件的SQL路由,SQL改写等性能都是基于对SQL的了解来进行的。所以SQL解析是数据库中间件的重要性能之一。 SQL作为数据库查询语言,对SQL的解析与其余任何一门语言的解析都一样,包含词法剖析、语法分析。我之前也写过一篇对于DBLE SQL解析的文章,大家能够在公众号中搜寻进一步浏览理解。 SQL实现解析后,下一步天然是执行,数据库中间件尽管大部分场景能够将SQL下推到数据库节点执行,但有一些简单SQL还是须要在中间件这一层进行解决的,这里又波及到执行打算的优化,返回后果解决算法等,这些内容能够说是属于重难点内容了。 2、 事务 事务是数据库的外围概念,对于数据库中间件来讲事务也同样重要。尤其是在分布式事务的场景下,数据库中间件作为事务协调器的角色,对事务的了解,能帮忙你了解该场景下数据库中间件是如何保证数据的一致性的。 3、 数据库协定 数据库中间件对外理论体现为数据库服务端。这里就波及到数据库协定的解决。 DBLE实现了MySQL协定,所以你连贯DBLE会发现和连贯MySQL的成果一样。对于DBLE的开发,你须要对MySQL协定有肯定的理解,MySQL的协定,大家能够参考上面的链接。 https://dev.mysql.com/doc/int...4、 复制 对于数据库的高可用,只能通过复制的形式来实现。 对于数据库中间件来讲,读写拆散性能可能利用数据库从节点进行读取,进而晋升利用的吞吐量,升高主节点的负载。所以数据库的主从复制,对于数据库中间件开发人员也是须要理解的。 最初本文列举了中间件开发所须要的一些技能,心愿能让大家对于中间件开发有肯定的理解,更进一步心愿能帮忙对中间件开发感兴趣的同学如何开始学习有个方向上的帮忙。 可能有同学会感觉要学习的货色这么多,什么时候能力真正具备开发中间件的技能呀。 其实咱们不须要等事件齐全筹备好了再去做,因为你可能会感觉筹备工作永远都不够充沛。所以无妨找一个简略的切入点开始实际,例如对于DBLE一个小小的bug修复,一个配置的批改,尝试去参加批改源码,在此过程中置信DBLE的官网团队也会给予你相应的帮忙。 心愿明天的文章能帮忙大家理解中间件的开发。

May 27, 2021 · 1 min · jiezi

关于中间件:两行代码修复了解析MySQL8x-binlog错位的问题

写在后面MySQL是互联网行业应用的最多的关系型数据库之一,而且MySQL又是开源的,对于MySQL的深入研究,可能加深咱们对于数据库原理的了解。自从开源了mykit-data之后,不少小伙伴试用后,反馈mykit-data无奈正确的解析MySQL8的binlog。于是我测试了下,mykit-data在解析MySQL5.x的binlog时,没有啥问题,可能正确的解析出后果数据。然而,在解析MySQL8.x的binlog时,总是与binlog日志位数相差12位而导致解析失败。 文章已收录到: https://github.com/sunshinelyz/technology-binghe https://gitee.com/binghe001/technology-binghe 问题修复明天太晚了,我还在钻研MySQL 8.0.20的源码,问题的修复过程后续再写一篇具体的文章来与小伙伴们分享下。这里,我就间接说我是如何解决这个问题的。 MySQL5.x binlog的解析后果与MySQL8.x binlog的解析后果总是存在位数偏差,框架本来的代码间接解析MySQL 5.x是没啥问题的,在解析MySQL 8.x的时候呈现位数谬误。 期间,我简直翻阅了MySQL的所有官网文档,把mykit-data中对于解析binlog日志的性能从新写了一遍,解析MySQL5.x没问题,解析MySQL8.x还是错位。 到底哪里出了问题呢?就在对于问题的解决束手无策的时候,忽然,想到一个思路:解决MySQL8.x binlog的时候不是总错位吗?那我就把多余位数的binlog数据读取进去,间接疏忽掉,使后续binlog的解析操作对齐不就行了吗? 连忙尝试一下,于是我在mykit-data框架的源码中,增加了如下代码。 下面代码是对解析MySQL binlog位数的校验和读取的封装,当读取的binlog位数未达到读取的限度位数时,始终读取binlog的数据,直到读取的binlog位数达到读取的限度位数地位。具体外部的逻辑,小伙伴们能够浏览mykit-data的源码。 加上这个逻辑后,进行测试验证,解析MySQL 8.x数据库的binlog居然胜利了!!困扰我几天的问题就这么在不经意间解决了!! 从解决这个问题的后果来看,MySQL8.x的binlog在实质上比MySQL5.x的binlog位数要长,两头会拼接用来分隔不同事件位的标识,咱们在解析MySQL8.x的binlog日志时,可间接疏忽掉这些分隔不同事件位的标识,目标就是让binlog的解析位对齐,从而可能正确的解析出下一个事件。而这样解决,也不会影响解析后果。 很多时候就是这样,当你苦于解决某个问题,迟迟找不到解决方案而束手无策时,在某个不经意的霎时,就会无心中解决这个辣手的问题,但前提是你须要深刻理解它的原理并尝试各种形式和办法来解决它! 对于mykit-datamykit-data是一款齐全开源的数据异构中间件,反对插件化、可视化的数据异构框架,反对MySQL到MySQL、MySQL到Oracle、Oracle到MySQL、Oracle到Oracle的全量、实时/定时增量数据同步。齐全的插件化、可视化操作。通过日志最大限度的防止同步过程中的数据失落。反对失败重试,人工干预,反对查看同步的数据和具体的日志信息。 目前反对MySQL5.x、MySQL8.x,Oracle 11g及以上版本。后续会以插件的模式反对更多的异构数据源。 mykit-data的开源地址如下: GitHub:https://github.com/sunshinelyz/mykit-data Gitee:https://gitee.com/binghe001/mykit-data 最初,小伙伴们为这款开源我的项目点个Star呀!! 好了,明天就到这儿吧,我是冰河,大家有啥问题能够在下方留言,咱们下期见~~

January 19, 2021 · 1 min · jiezi

关于中间件:软件测试详解12中间件介绍

一、Tomcat1、Tomcat概念 Tomcat 服务器是一个开源的轻量级Web应用服务器,在中小型零碎和并发量小的场合下被广泛应用,是开发和调试Servlet、JSP 程序的首选。 2、原理 Tomcat次要组件:服务器Server,服务Service,连接器Connector、容器Container。连接器Connector和容器Container是Tomcat的外围。 一个Container容器和一个或多个Connector组合在一起,加上其余一些反对的组件独特组成一个Service服务,有了Service服务便能够对外提供能力了,然而Service服务的生存须要一个环境,这个环境便是Server,Server组件为Service服务的失常应用提供了生存环境,Server组件能够同时治理一个或多个Service服务。 二、nginx1、nginx简介 nginx(发音同engine x)是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like协定下发行。 nginx的特点是占有内存少,并发能力强,事实上nginx的并发能力的确在同类型的网页服务器中体现较好,中国大陆应用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。 2、nginx的个性与长处 1)nginx的个性 Nginx应用基于事件驱动架构,使得其能够反对数以百万级别的TCP连贯高度的模块化和自由软件许可证是的第三方模块层出不穷(这是个开源的时代啊~)Nginx是一个跨平台服务器,能够运行在Linux,Windows,FreeBSD,Solaris, AIX,Mac OS等操作系统上这些优良的设计带来的极大的稳定性2) nginx的长处 高并发连贯:官网测试可能撑持5万并发连贯,在理论生产环境中跑到2-3万并发连接数内存耗费少:在3万并发连贯下,开启的10个nginx过程才耗费150M内存(15M*10=150M)配置文件非常简单:格调跟程序一样通俗易懂老本低廉:nginx为开源软件,能够收费应用。而购买F5 BIG-IP、NetScaler等硬件负载平衡交换机则须要十多万至几十万人民币反对Rewrite重写规定:可能依据域名、URL的不同,将HTTP申请分到不同的后端服务器群组内置的健康检查性能:如果Nginx Proxy后端的某台Web服务器宕机了,不会影响前端拜访节俭带宽:反对GZIP压缩,能够增加浏览器本地缓存的Header头稳定性高:用于反向代理,宕机的概率微不足道模块化设计:模块能够动静编译外围反对好:文档全,二次开发和模块较多反对热部署:能够不停机重载配置文件反对事件驱动、AIO(AsyncIO,异步IO)、mmap(Memory Map,内存映射)等性能优化3、nginx反向代理 多个客户端给服务器发送的申请,Nginx服务器接管到之后,依照肯定的规定分发给了后端的业务解决服务器进行解决了。此时~申请的起源也就是客户端是明确的,然而申请具体由哪台服务器解决的并不明确了,Nginx表演的就是一个反向代理角色。 客户端是无感知代理的存在的,反向代理对外都是通明的,访问者并不知道本人拜访的是一个代理。因为客户端不须要任何配置就能够拜访。 反向代理,“它代理的是服务端”,次要用于服务器集群分布式部署的状况下,反向代理暗藏了服务器的信息。 三、Apache1、Apache简介 Apache HTTP Server(简称Apache)是Apache软件基金会的一个开放源码的网页服务器,是世界应用排名第一的Web服务器软件。它能够运行在简直所有宽泛应用的计算机平台上,因为其跨平台和安全性被宽泛应用,是最风行的Web服务器端软件之一。它疾速、牢靠并且可通过简略的API裁减,将Perl/Python等解释器编译到服务器中。 Apache HTTP服务器是一个模块化的服务器,源于NCSAhttpd服务器,通过屡次批改,成为世界应用排名第一的Web服务器软件。Apache取自“a patchy server”的读音,意思是充斥补丁的服务器,因为它是自由软件,所以一直有人来为它开发新的性能、新的个性、批改原来的缺点。Apache的特点是简略、速度快、性能稳固,并可做代理服务器来应用。 原本它只用于小型或试验Internet网络,起初逐渐裁减到各种Unix零碎中,尤其对Linux的反对相当完满。Apache有多种产品,能够反对SSL技术,反对多个虚拟主机。Apache是以过程为根底的构造,过程要比线程耗费更多的零碎开销,不太适宜于多处理器环境,因而,在一个Apache Web站点扩容时,通常是减少服务器或裁减群集节点而不是减少处理器。 四、Lighttpd最风行的Apache服务器替代者,Lighttpd是一个单线程的针对大量继续连贯做出专门优化的Web服务器(这正是少数高流量网站和应用程序须要的)。泛滥的风行Web站点抉择Lighttpd,包含Youtube、SourceForge和维基百科。Lighttpd反对FastCGI、HTTP服务器端压缩、mod-rewrite和其余泛滥有用的性能。只管Lighttpd领有Apache的绝大多数性能,但它依然放弃轻量级(仅1MB)并且能够与Apache应用雷同的配置。 五、kanglekangleweb服务器(简称:kangle)是一款跨平台、功能强大、平安稳固、易操作的高性能web服务器和反向代理服务器软件。除此:kangle也是一款专为做虚拟主机研发的web服务器。实现虚拟主机独立过程、独立身份运行。用户之间平安隔离,一个用户出问题不影响其余用户。平安反对php、asp、asp·net、java、ruby等多种动静开发语言。 六、Boa很多的网站管理员对在硬件配置较低的服务器上应用轻量级的Boa作为Web服务器极其信赖。Boa是一个单线程的HTTP服务器,这意味着Boa只能顺次实现用户的申请而不会fork新的过程来解决并发申请。Boa的设计目标是速度和平安,对于运行于单服务器的风行Web站点而言,Boa是一个好的抉择。 七、JigsawJigsaw是W3C推出的开源的Web服务器平台,应用Java语言编写,能够装置在有Java运行环境的零碎上。做为W3C(World Wide Web Consortium)开发的服务器产品,其作用次要是对新技术的实现做一个例示,而非一个全功能的商业服务器产品。不过就Jigsaw 2.0版本而言,它的性能还是超过了Web服务器的平均水平。最重要的是,它体现了将来HTTP协定和基于对象的Web服务器技术的倒退。如果你心愿你的平台反对所有下一代技术,Jigsaw是一个好的抉择。 接口测试和接口文档生成工具:apipost

January 6, 2021 · 1 min · jiezi

关于中间件:消息模型主题和队列有什么区别

能够看到,技术圈的风向始终在变,大数据、云的热度曾经在缓缓消退,当初当红的是 AI 和 IoT。这些炽热的概念,它最终要从论文和 PPT 落地,变成真正能解决问题的零碎,否则就是一个海市蜃楼。那不变的是什么?(一些题外话的感触) 主题和队列有什么区别?最后的音讯队列,就是一个严格意义上的队列 消费者之间实际上是竞争的关系,每个消费者只能收到队列中的一部分音讯 如果须要将一份音讯数据分发给多个消费者,要求每个消费者都能收到全量的音讯,例如,对于一份订单数据,风控系统、剖析零碎、领取零碎等都须要接管音讯。这个时候,单个队列就满足不了需要,一个可行的解决形式是,为每个消费者创立一个独自的队列,让生产者发送多份 (不好的做法). 为了解决这个问题,演化出了另外一种音讯模型:“公布 - 订阅模型(Publish-Subscribe Pattern)”。 在公布 - 订阅模型中,音讯的发送方称为发布者(Publisher),音讯的接管方称为订阅者(Subscriber),服务端寄存音讯的容器称为主题(Topic)。发布者将音讯发送到主题中,订阅者在接管音讯之前须要先“订阅主题”。“订阅”在这里既是一个动作,同时还能够认为是主题在生产时的一个逻辑正本,每份订阅中,订阅者都能够接管到主题的所有音讯。 古代的音讯队列产品应用的音讯模型大多是这种公布 - 订阅模型 RabbitMQ的音讯模型它是多数仍然保持应用队列模型的产品之一. 在 RabbitMQ 中,Exchange 位于生产者和队列之间,生产者并不关怀将音讯发送给哪个队列,而是将音讯发送给 Exchange,由 Exchange 上配置的策略来决定将音讯投递到哪些队列中。 同一份音讯如果须要被多个消费者来生产,须要配置 Exchange 将音讯发送到多个队列,每个队列中都寄存一份残缺的音讯数据,能够为一个消费者提供生产服务。 这也能够变相地实现新公布 - 订阅模型中,“一份音讯数据能够被多个订阅者来屡次生产”这样的性能。 RocketMQ的音讯模型RocketMQ 应用的音讯模型是规范的公布 - 订阅模型 确认机制很好地保障了消息传递过程中的可靠性,然而,引入这个机制在生产端带来了一个不小的问题。为了确保音讯的有序性,在某一条音讯被胜利生产之前,下一条音讯是不能被生产的,否则就会呈现音讯空洞,违反了有序性这个准则。 也就是说,每个主题在任意时刻,至少只能有一个消费者实例在进行生产,那就没法通过程度扩大消费者的数量来晋升生产端总体的生产性能。为了解决这个问题,RocketMQ 在主题上面减少了队列的概念。 每个主题蕴含多个队列,通过多个队列来实现多实例并行生产和生产RocketMQ 只在队列上保障音讯的有序性,主题层面是无奈保障音讯的严格程序的 (同一队列有序, 队列之间无序)RocketMQ 中,订阅者的概念是通过生产组(Consumer Group)来体现的。每个生产组都生产主题中一份残缺的音讯,不同生产组之间生产进度彼此不受影响,也就是说,一条音讯被 Consumer Group1 生产过,也会再给 Consumer Group2 生产。 生产组中蕴含多个消费者,同一个组内的消费者是竞争生产的关系,每个消费者负责生产组内的一部分音讯。如果一条音讯被消费者 Consumer1 生产了,那同组的其余消费者就不会再收到这条音讯。 在 Topic 的生产过程中,因为音讯须要被不同的组进行屡次生产,所以生产完的音讯并不会立刻被删除,这就须要 RocketMQ 为每个生产组在每个队列上保护一个生产地位(Consumer Offset),这个地位之前的音讯都被生产过,之后的音讯都没有被生产过,每胜利生产一条音讯,生产地位就加一。这个生产地位是十分重要的概念,咱们在应用音讯队列的时候,丢音讯的起因大多是因为生产地位处理不当导致的。 Kafka的音讯模型Kafka 的音讯模型和 RocketMQ 是齐全一样的. ...

November 13, 2020 · 1 min · jiezi

关于中间件:面试官问我看过shardingjdbc的源码吗我吧啦吧啦说了一通

写在后面在产品初期疾速迭代的过程中,往往为了疾速上线而占据市场,在后端开发的过程中往往不会过多的思考分布式和微服务,往往会将后端服务做成一个单体利用,而数据库也是一样,最后会把所有的业务数据都放到一个数据库中,即所谓的单实例数据库。随着业务的迅速倒退,将所有数据都放在一个数据库中曾经不足以撑持业务倒退的须要。此时,就会对系统进行分布式革新,而数据库业务进行分库分表的拆分。那么,问题来了,如何更好的拜访和治理拆分后的数据库呢?业界曾经有很多成熟的解决方案,其中,一个十分优良的解决方案就是:Apache ShardingSphere。明天,咱们就从源码级别来独特探讨下sharding-jdbc的外围源码。sharding-jdbc经典用法Sharding-Jdbc 是一个轻量级的分库分表框架,应用时最要害的是配置分库分表策略,其余的和应用一般的 MySQL 驱动一样,简直不必改代码。例如上面的代码片段。 try(DataSource dataSource = ShardingDataSourceFactory.createDataSource( createDataSourceMap(), shardingRuleConfig, new Properties()) { Connection connection = dataSource.getConnection(); ...}咱们在程序中拿到Connection对象后,就能够像应用一般的JDBC一样来应用sharding-jdbc操作数据库了。 sharding-jdbc包构造sharding-jdbc ├── sharding-jdbc-core 重写DataSource/Connection/Statement/ResultSet四大对象 └── sharding-jdbc-orchestration 配置核心sharding-core ├── sharding-core-api 接口和配置类 ├── sharding-core-common 通用分片策略实现... ├── sharding-core-entry SQL解析、路由、改写,外围类BaseShardingEngine ├── sharding-core-route SQL路由,外围类StatementRoutingEngine ├── sharding-core-rewrite SQL改写,外围类ShardingSQLRewriteEngine ├── sharding-core-execute SQL执行,外围类ShardingExecuteEngine └── sharding-core-merge 后果合并,外围类MergeEngineshardingsphere-sql-parser ├── shardingsphere-sql-parser-spi SQLParserEntry,用于初始化SQLParser ├── shardingsphere-sql-parser-engine SQL解析,外围类SQLParseEngine ├── shardingsphere-sql-parser-relation └── shardingsphere-sql-parser-mysql MySQL解析器,外围类MySQLParserEntry和MySQLParsershardingsphere-underlying 根底接口和api ├── shardingsphere-rewrite SQLRewriteEngine接口 ├── shardingsphere-execute QueryResult查问后果 └── shardingsphere-merge MergeEngine接口shardingsphere-spi SPI加载工具类sharding-transaction ├── sharding-transaction-core 接口ShardingTransactionManager,SPI加载 ├── sharding-transaction-2pc 实现类XAShardingTransactionManager └── sharding-transaction-base 实现类SeataATShardingTransactionManagersharding-jdbc中的四大对象所有的所有都从 ShardingDataSourceFactory 开始的,创立了一个 ShardingDataSource 的分片数据源。除了 ShardingDataSource(分片数据源),在 Sharding-Sphere 中还有 MasterSlaveDataSourceFactory(主从数据源)、EncryptDataSourceFactory(脱敏数据源)。 ...

October 29, 2020 · 4 min · jiezi

关于中间件:Zebra

1.背景 Zebra是一个基于JDBC API协定上开发出的高可用、高性能的数据库拜访层解决方案。相似阿里的tddl,zebra是一个smart客户端,提供了诸如动静配置、监控、读写拆散、分库分表等性能。zebra是由基础架构团队开发和保护,定位是公司对立的数据库拜访层组件(Data Access Layer),是新美大DBA团队举荐的官网数据源组件,未来也会以zebra为外围进行数据拜访层的演进。 Zebra最后是上海侧数据库拜访组件,目前上海侧全量利用应用该组件拜访数据库。2016年Q3之后,北京侧逐渐放弃应用atlas,外卖配送、酒旅、到餐、猫眼等事业部,都陆陆续续开启接入zebra。 截止2018年6月27日,公司已有8000+利用接入了zebra,整体覆盖率达到94.66%。对于java利用,都倡议应用zebra去拜访数据库。 简化了读写拆散、分库分表的开发工作,使得业务方在分库分库、读写拆散的状况下,仍然能够像操作单个库那样去操作,屏蔽底层实现的复杂性,对业务通明。提供了从读写拆散到分库分表全生命周期的技术支持。 2.组成zebra次要是以客户端的模式提供服务,客户端又细分为3个组件:zebra-api、zebra-dao、zebra-ds-monitor-client。 zebra-api(外围)除了监控外,简直zebra所有外围性能,如读写拆散、分库分表、全链路压测、Set化反对、就近路由、流量管制、故障模拟都是通过zebra-api来提供的。zebra-ds-monitor-client提供端到端的监控,将监控信息上报到cat、falcon、mtrace。zebra-dao对mybatis的轻量级封装,所有mybatis原有的性能都具备,额定提供了异步化接口、分页插件、多数据源等性能。2.1zebra-api(外围依赖)2.1.1 读写拆散作为一个拜访层组件,读写拆散是一个根本要求。 zebra目前反对的如下能力: 反对程度扩大从库,灵便的调整各个从库的任意流量比例反对优先就近抉择从库进行读取数据,防止跨机房拜访灵便的强制走主库策略,反对单条SQL或者整个申请内所有SQL等维度......2.1.2 分库分表目前分库分表反对能力如下: 同时反对分库和分表,路由策略能够通过groovy脚本进行灵便定制分表键反对 =,in等操作符欠缺的SQL解析,反对聚合,分组,排序,Limit等语句反对多维度的分表策略配置均集中式配置和存储,简化业务代码的配置文件......分库分表除了落地到客户端的能力上,zebra还在运维能力上进行继续晋升。因次,zebra能够说为分库分表打造了一站式的解决方案,具体包含以下的能力: 一键的建库建表和DDL变更操作反对路由后果的可视化查问反对多维度的数据自动化同步......2.1.3 高可用高可用架构如下所示: 在整体架构图中能够看到,目前整个数据库的高可用应用到了两个组件,其中一个开源组件是MHA,它来负责主库的检测和切换。另外一个是自研服务,它用来负责从库的可用性检测和故障时从库的摘除。 然而一旦业务的性能差的SQL打到数据库上时,DBA就须要对这条SQL进行解决。目前反对SQL限流和SQL改写两种策略。首先,DBA能够把引发故障的慢SQL在治理端上配置流量进入的比例,这样一来该SQL就不会再打到数据库上从而引发数据库故障。而后,DBA还能够在保障语义齐全一样的状况下,在治理端在线对这条SQL进行改写,这样一来客户端发往数据库的将是DBA优化过的SQL了。 2.1.4 全链路压测可能反对对压测流量中的SQL的数据库表名进行动静改写,从而使得压测流量都落到新的数据库表中,而不影响失常业务的数据库表。这样做的益处是,不必再麻烦费劲去搭建一套性能环境进行压测,而是间接应用的线上的物理设施进行压测,因为这样能力更好的压测出性能瓶颈。 2.1.5 就近路由为了满足高可用的需要,mysql集群和业务服务器集群个别须要进行多机房/多核心部署,为此会产生跨机房/核心拜访的问题。为了均衡跨机房/核心拜访带来的提早问题,须要利用机器可能优先拜访部署在同一机房/核心的DB。 2.1.6 故障模拟业务方有时须要模仿在数据库宕机的状况下服务的可用性。zebra反对模仿主库/从库宕机,以及模仿单个SQL执行失败。 2.1.7 SET化反对我司外卖业务体量宏大,业务已冲破1600W/天。以后,咱们通过一个大型分布式集群来反对业务,集群外部进行了大量的拆分(数据库、MQ、缓存等),具备了肯定的可扩展性。然而,随着业务量的进一步增长,局部组件的可扩展性遇到了肯定问题。同时,随着集群规模的扩充,须要计算资源越来越多,单IDC已不能满足需要,以后架构在IDC扩大时,会遇到肯定问题。SET化性能次要是为了在存储层反对单元化架构。 2.1.8 流量管制在零碎访问量较大时,某些库的负载可能十分高,或者因为长期故障或零碎bug导致大量异样SQL打到某个库上。为了避免数据库被这些异样流量打垮,须要在数据库拜访层上对MySQL进行爱护,因而zebra须要提供对某些特定SQL或某个库进行限流的性能。(SQL限流只是用于长期解决问题,预先还需业务方进行优化或扩容) 2.2 zebra-ds-monitor-client2.2.1 端到端监控端到端的监控,一端指的是应用服务器,另一端指的是数据库服务器,一次端到端过程,就是一次残缺的申请响应过程,两头经验两次来回网络的开销。端到端监控之所以重要,因为它最可能主观的反映SQL的性能。比起MySQL服务端的监控指标,端到端监控还把来回的两次网络开销算了进去。过往的历史教训来看,会经常出现在端到端监控上看到慢查问,但这条慢查问却不可能在MySQL服务器上查出,这是因为有可能这条SQL在网络上多花了开销,或者在MySQL的队列中多期待了一段时间。 因而,端到端的监控是如此的重要! zebra应用的是cat来进行端到端的监控,也反对把监控指标打到mtrace上。在这些监控平台上,能够明确的看到具体的某条SQL的性能指标,包含均匀响应工夫、99线、999线等。在CAT上还可能抓取出慢查问报表通知开发,而后开发对这些慢查问进行优化。 举例来说,上图是CAT上SQL打点的一个截图,从中能够看到以下信息: 从连接池拿到连贯花了0.01ms(SQL.Conn)整个SQL(UserProfile.loadUserProfile)的执行开始工夫(15:13:23.010)和 完结工夫(15:13:23.011)这条SQL查问的后果为 0 (SQL.Rows)在dpuser-n1-read数据库上进行了查问Select这条SQL具体的SQL是:SELECT UserID,......,和这条PreparedStatement须要的参数是:115522257这条SQL总共执行了1.48ms整个调用链路上SQL的地位2.3 zebra-dao对mybatis的轻量级封装,所有mybatis原有的性能都具备,额定提供了异步化接口、分页插件、多数据源等性能。用法实质上就是mybatis的用法。 2.3.1 异步化接口一个服务可能包含RPC调用申请、MemCached申请、KV存储申请以及MySQL数据库调用,目前我司其它三种申请的组件都有异步化的接口,然而数据库调用并没有。所以,在这个状况下,开发了这个异步化的DAO。目前,公司外部已有多个业务接入应用,曾经承受了线上环境的验证和考验。 2.3.2 分页插件反对逻辑分页和物理分页 2.3.3 多数据源反对配置多个数据源,通过注解的形式指应该应用哪个数据源。

September 25, 2020 · 1 min · jiezi

关于中间件:介绍-7-款神秘的开源中间件

作者:码云Gitee 起源:toutiao.com/i6782485898526196236在系统软件之中,操作系统、数据库、中间件的三驾马车,中间件是最神秘的,而且是一个专业化十分强的细分产业。中间件技术次要用来撑持分布式软件的开发,在大型分布式软件系统中中间件技术施展着极其重要的作用。明天,小编举荐 7 款 Gitee 上的中间件开源我的项目,心愿可能让你领会到中间件技术的魅力。 1、高性能 Redis 中间件服务 nredis-proxy 我的项目简介:nredis-proxy 是一个以 redis 协定为主的高性能稳固的代理中间件服务,不侵入业务代码,与业务毫无分割,不须要改任何利用代码,人造反对分布式部署。 我的项目地址:https://gitee.com/284520459/n... 2、.net 业务音讯队列 Dyd.BusinessMQ 我的项目简介:.net 业务音讯队列是利用于业务的解耦和拆散,应具备分布式,高可靠性,高性能,高实时性,高稳定性,高扩展性等个性,其长处次要是: 大量的业务音讯沉积能力无单点故障及故障监控,异样揭示生产者端负载平衡,故障转移,故障主动复原,并行音讯插入。消费者端负载平衡,故障放弃,故障主动复原,并行音讯生产。音讯高可靠性长久化,较高性能,较高实时性,高稳定性,高扩展性。反对99*99个音讯分区,单个音讯分区单天反对近1亿的音讯存储。消费者拉形式获取音讯,在高并发,大量音讯涌入的状况下,只有生产能力足够,不会有音讯提早,音讯越多性能越好。我的项目地址:https://gitee.com/chejiangyi/... 3、基于 RabbitMQ 实现的消息中间件 WMQ 我的项目简介:WMQ 是用 Golang 编写的基于 RabbitMQ 实现的消息中间件,在零碎架构对解耦现有业务起到至关重要的作用,服务基于 HTTP 的 API 形式具备跨语言的特点,接入非常简略。可能很好的解决并发管制,异步工作,以及音讯订阅与散发。 我的项目地址:https://gitee.com/snail/wmq-go 4、开源实时音讯推送零碎 MPush 我的项目简介:mpush,是一款开源的实时音讯推送零碎,采纳 java 语言开发,服务端采纳模块化设计,具备协定简洁,传输平安,接口晦涩,实时高效,扩展性强,可配置化,部署不便,监控欠缺等特点。同时也是少有的可商用的开源push推送零碎。 我的项目地址:https://gitee.com/mpush/mpush 5、分布式 TCP 推送零碎 GPush我的项目简介:一个 linux 下高效的,分布式 TCP 推送零碎实现,单台连贯服务器撑持超过百万以上连贯,次要实用于千万在线级别规模的利用,比照第三方推送平台,次要劣势在于,服务自建,推送效率高,而且能够很不便进行性能扩大。 我的项目地址:https://gitee.com/gsfw/GPush 6、轻量级Java消息中间件 Uncode-MQ 我的项目简介:java 轻量级消息中间件,其性能特点如下: 音讯存储速度十分疾速。应用简略不便,目前只反对 topic 形式。依赖 java 环境。我的项目地址:https://gitee.com/uncode/unco... 7、MQ、RPC、服务总线 zbus 我的项目简介:zbus 外围是一个独立实现的玲珑极速的音讯队列(MQ),反对长久化与内存队列, 反对单播、播送、组播等多种音讯通信模式;在 MQ 之上 zbus 齐备地反对了 RPC 服务,RPC 反对独立伺服,基于总线两种模式;同时 zbus 反对代理服务,基于 MQ 的 HttpProxy 实现了类 Nginx 的 HTTP 代理服务(反对 DMZ 网络结构),TcpProxy 则反对通明的 TCP 协定代理,能够代理任何基于 TCP 的协定,比方代理 MySQL 数据库。 ...

August 14, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-下载

最新版本全副版本校验版本最新版本ShardingSphere的公布版包含源码包及其对应的二进制包。因为下载内容散布在镜像服务器上,所以下载后应该进行GPG或SHA-512校验,以此来保障内容没有被篡改。 具体下载地址见: https://shardingsphere.apache.org/document/legacy/4.x/document/cn/downloads/ 全副版本全副版本请到Archive repository查看。 全副孵化器版本请到Archive incubator repository查看。 校验版本PGP签名文件 应用PGP或SHA签名验证下载文件的完整性至关重要。能够应用GPG或PGP验证PGP签名。请下载KEYS以及公布的asc签名文件。倡议从主公布目录而不是镜像中获取这些文件。 gpg -i KEYSor pgpk -a KEYSor pgp -ka KEYS要验证二进制文件或源代码,您能够从主公布目录下载相干的asc文件,并依照以下指南进行操作。 gpg --verify apache-shardingsphere-********.asc apache-shardingsphere-*********or pgpv apache-shardingsphere-********.ascor pgp apache-shardingsphere-********.asc

July 26, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-ShardingUI-注册中心使用手册

注册核心配置首先须要增加并激活注册核心。能够增加多个注册核心,但只能有一个处于激活状态,前面的运行状态性能都是针对以后已激活的注册核心进行操作。目前提供Zookeeper的反对,后续会增加第三方注册核心的反对。 运行状态增加激活注册核心后,能够查看以后注册核心所有运行实例信息。能够通过操作按钮对运行实例进行熔断与复原操作。能够查看所有从库信息,并进行从库禁用与复原操作。

July 26, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-ShardingUI-用户手册

简介Sharding-UI是ShardingSphere的一个简略而有用的web治理控制台。它用于帮忙用户更简略的应用ShardingSphere的相干性能,目前提供注册核心治理、动静配置管理、数据库编排等性能。 我的项目构造上采取了前后端拆散的形式,前端应用Vue框架,后端采纳Spring Boot框架。应用规范的Maven形式进行打包,部署,同时也能够采纳前后端拆散的形式本地运行,不便开发调试。

July 26, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-ShardingUI-用户手册

简介Sharding-UI是ShardingSphere的一个简略而有用的web治理控制台。它用于帮忙用户更简略的应用ShardingSphere的相干性能,目前提供注册核心治理、动静配置管理、数据库编排等性能。 我的项目构造上采取了前后端拆散的形式,前端应用Vue框架,后端采纳Spring Boot框架。应用规范的Maven形式进行打包,部署,同时也能够采纳前后端拆散的形式本地运行,不便开发调试。

July 26, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-ShardingSidecar-用户手册

简介Sharding-Sidecar是ShardingSphere的第三个产品,目前依然在布局中。定位为Kubernetes或Mesos的云原生数据库代理,以DaemonSet的模式代理所有对数据库的拜访。 通过无核心、零侵入的计划提供与数据库交互的的啮合层,即Database Mesh,又可称数据网格。Database Mesh的关注重点在于如何将分布式的数据拜访利用与数据库有机串联起来,它更加关注的是交互,是将横七竖八的利用与数据库之间的交互无效的梳理。应用Database Mesh,拜访数据库的利用和数据库终将造成一个微小的网格体系,利用和数据库只需在网格体系中对号入座即可,它们都是被啮合层所治理的对象。 比照 Sharding-JDBCSharding-ProxySharding-Sidecar数据库任意MySQLMySQL连贯耗费数高低高异构语言仅Java任意任意性能损耗低损耗略高损耗低无中心化是否是动态入口无有无Sharding-Sidecar的劣势在于对Kubernetes和Mesos的云原生反对。

July 26, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-ShardingSidecar-用户手册

简介Sharding-Sidecar是ShardingSphere的第三个产品,目前依然在布局中。定位为Kubernetes或Mesos的云原生数据库代理,以DaemonSet的模式代理所有对数据库的拜访。 通过无核心、零侵入的计划提供与数据库交互的的啮合层,即Database Mesh,又可称数据网格。Database Mesh的关注重点在于如何将分布式的数据拜访利用与数据库有机串联起来,它更加关注的是交互,是将横七竖八的利用与数据库之间的交互无效的梳理。应用Database Mesh,拜访数据库的利用和数据库终将造成一个微小的网格体系,利用和数据库只需在网格体系中对号入座即可,它们都是被啮合层所治理的对象。 比照 Sharding-JDBCSharding-ProxySharding-Sidecar数据库任意MySQLMySQL连贯耗费数高低高异构语言仅Java任意任意性能损耗低损耗略高损耗低无中心化是否是动态入口无有无Sharding-Sidecar的劣势在于对Kubernetes和Mesos的云原生反对。

July 26, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-ShardingProxy-DOCKER镜像

拉取官网Docker镜像docker pull apache/sharding-proxy手动构建Docker镜像(可选)git clone https://github.com/apache/shardingspheremvn clean installcd sharding-sphere/sharding-distribution/sharding-proxy-distributionmvn clean package -Prelease,docker配置Sharding-Proxy在/${your_work_dir}/conf/创立server.yaml和config-xxx.yaml文件,进行服务器和分片规定配置。配置规定,请参考配置手册。配置模板,请参考配置模板 运行Dockerdocker run -d -v /${your_work_dir}/conf:/opt/sharding-proxy/conf -e PORT=3308 -p13308:3308 apache/sharding-proxy:latest阐明 能够自定义端口3308和13308。3308示意docker容器端口, 13308示意宿主机端口。必须挂载配置门路到/opt/sharding-proxy/conf。docker run -d -v /${your_work_dir}/conf:/opt/sharding-proxy/conf -e JVM_OPTS="-Djava.awt.headless=true" -e PORT=3308 -p13308:3308 apache/sharding-proxy:latest阐明 能够自定义JVM相干参数到环境变量JVM_OPTS中。docker run -d -v /${your_work_dir}/conf:/opt/sharding-proxy/conf -v /${your_work_dir}/ext-lib:/opt/sharding-proxy/ext-lib -p13308:3308 apache/sharding-proxy:latest阐明 如需应用内部jar包,可将其所在目录挂载到/opt/sharding-proxy/ext-lib。拜访Sharding-Proxy与连贯PostgreSQL的形式雷同。 psql -U ${your_user_name} -h ${your_host} -p 13308FAQ问题1:I/O exception (java.io.IOException) caught when processing request to {}->unix://localhost:80: Connection refused? 答复:在构建镜像前,请确保docker daemon过程曾经运行。 问题2:启动时报无奈连贯到数据库谬误? 答复:请确保/${your_work_dir}/conf/config-xxx.yaml配置文件中指定的PostgreSQL数据库的IP能够被Docker容器外部拜访到。 问题3:如何应用后端数据库为MySQL的ShardingProxy? 答复:将mysql-connector.jar所在目录挂载到/opt/sharding-proxy/ext-lib。 问题4:如何应用自定义分片算法? ...

July 26, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-ShardingProxy-DOCKER镜像

拉取官网Docker镜像docker pull apache/sharding-proxy手动构建Docker镜像(可选)git clone https://github.com/apache/shardingspheremvn clean installcd sharding-sphere/sharding-distribution/sharding-proxy-distributionmvn clean package -Prelease,docker配置Sharding-Proxy在/${your_work_dir}/conf/创立server.yaml和config-xxx.yaml文件,进行服务器和分片规定配置。配置规定,请参考配置手册。配置模板,请参考配置模板 运行Dockerdocker run -d -v /${your_work_dir}/conf:/opt/sharding-proxy/conf -e PORT=3308 -p13308:3308 apache/sharding-proxy:latest阐明 能够自定义端口3308和13308。3308示意docker容器端口, 13308示意宿主机端口。必须挂载配置门路到/opt/sharding-proxy/conf。docker run -d -v /${your_work_dir}/conf:/opt/sharding-proxy/conf -e JVM_OPTS="-Djava.awt.headless=true" -e PORT=3308 -p13308:3308 apache/sharding-proxy:latest阐明 能够自定义JVM相干参数到环境变量JVM_OPTS中。docker run -d -v /${your_work_dir}/conf:/opt/sharding-proxy/conf -v /${your_work_dir}/ext-lib:/opt/sharding-proxy/ext-lib -p13308:3308 apache/sharding-proxy:latest阐明 如需应用内部jar包,可将其所在目录挂载到/opt/sharding-proxy/ext-lib。拜访Sharding-Proxy与连贯PostgreSQL的形式雷同。 psql -U ${your_user_name} -h ${your_host} -p 13308FAQ问题1:I/O exception (java.io.IOException) caught when processing request to {}->unix://localhost:80: Connection refused? 答复:在构建镜像前,请确保docker daemon过程曾经运行。 问题2:启动时报无奈连贯到数据库谬误? 答复:请确保/${your_work_dir}/conf/config-xxx.yaml配置文件中指定的PostgreSQL数据库的IP能够被Docker容器外部拜访到。 问题3:如何应用后端数据库为MySQL的ShardingProxy? 答复:将mysql-connector.jar所在目录挂载到/opt/sharding-proxy/ext-lib。 问题4:如何应用自定义分片算法? ...

July 26, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-弹性伸缩实现原理

实现原理思考到ShardingSphere的弹性伸缩模块的几个挑战,目前的弹性伸缩解决方案为:长期地应用两个数据库集群,伸缩实现后切换的形式实现。 这种实现形式有以下长处: 伸缩过程中,原始数据没有任何影响。伸缩失败无风险。不受分片策略限度。同时也存在肯定的毛病: 在肯定工夫内存在冗余服务器所有数据都须要挪动弹性伸缩模块会通过解析旧分片规定,提取配置中的数据源、数据节点等信息,之后创立伸缩作业工作流,将一次弹性伸缩拆解为4个次要阶段 筹备阶段存量数据迁徙阶段增量数据同步阶段规定切换阶段 筹备阶段在筹备阶段,弹性伸缩模块会进行数据源连通性及权限的校验,同时进行存量数据的统计、日志位点的记录,最初依据数据量和用户设置的并行度,对工作进行分片。 存量数据迁徙阶段执行在筹备阶段拆分好的存量数据迁徙作业,存量迁徙阶段采纳JDBC查问的形式,间接从数据节点中读取数据,并应用新规定写入到新集群中。 增量数据同步阶段因为存量数据迁徙消耗的工夫受到数据量和并行度等因素影响,此时须要对这段时间内业务新增的数据进行同步。不同的数据库应用的技术细节不同,但总体上均为基于复制协定或WAL日志实现的变更数据捕捉性能。 MySQL:订阅并解析binlogPostgreSQL:采纳官网逻辑复制 test_decoding这些捕捉的增量数据,同样会由弹性伸缩模块依据新规定写入到新数据节点中。当增量数据根本同步实现时(因为业务零碎未进行,增量数据是一直的),则进入规定切换阶段。 规定切换阶段在此阶段,可能存在肯定工夫的业务只读窗口期,通过设置数据库只读或ShardingSphere的熔断机制,让旧数据节点中的数据短暂动态,确保增量同步已齐全实现。 这个窗口期工夫短则数秒,长则数分钟,取决于数据量和用户是否须要对数据进行强校验。确认实现后,ShardingSphere可通过配置核心批改配置,将业务导向新规定的集群,弹性伸缩实现。

July 24, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-数据分片内核剖析之路由引擎

依据解析上下文匹配数据库和表的分片策略,并生成路由门路。对于携带分片键的SQL,依据分片键的不同能够划分为单片路由(分片键的操作符是等号)、多片路由(分片键的操作符是IN)和范畴路由(分片键的操作符是BETWEEN)。不携带分片键的SQL则采纳播送路由。 分片策略通常能够采纳由数据库内置或由用户方配置。数据库内置的计划较为简单,内置的分片策略大抵可分为尾数取模、哈希、范畴、标签、工夫等。由用户方配置的分片策略则更加灵便,能够依据应用方需要定制复合分片策略。如果配合数据主动迁徙来应用,能够做到无需用户关注分片策略,主动由数据库中间层分片和均衡数据即可,进而做到使分布式数据库具备的弹性伸缩的能力。在ShardingSphere的线路布局中,弹性伸缩将于4.x开启。 分片路由用于依据分片键进行路由的场景,又细分为间接路由、规范路由和笛卡尔积路由这3种类型。 间接路由满足间接路由的条件绝对刻薄,它须要通过Hint(应用HintAPI间接指定路由至库表)形式分片,并且是只分库不分表的前提下,则能够防止SQL解析和之后的后果归并。因而它的兼容性最好,能够执行包含子查问、自定义函数等简单状况的任意SQL。间接路由还能够用于分片键不在SQL中的场景。例如,设置用于数据库分片的键为3, hintManager.setDatabaseShardingValue(3);如果路由算法为value % 2,当一个逻辑库t_order对应2个实在库t_order_0和t_order_1时,路由后SQL将在t_order_1上执行。下方是应用API的代码样例: String sql = "SELECT * FROM t_order";try ( HintManager hintManager = HintManager.getInstance(); Connection conn = dataSource.getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { hintManager.setDatabaseShardingValue(3); try (ResultSet rs = pstmt.executeQuery()) { while (rs.next()) { //... } }}规范路由规范路由是ShardingSphere最为举荐应用的分片形式,它的适用范围是不蕴含关联查问或仅蕴含绑定表之间关联查问的SQL。当分片运算符是等于号时,路由后果将落入单库(表),当分片运算符是BETWEEN或IN时,则路由后果不肯定落入惟一的库(表),因而一条逻辑SQL最终可能被拆分为多条用于执行的实在SQL。举例说明,如果依照order_id的奇数和偶数进行数据分片,一个单表查问的SQL如下: SELECT * FROM t_order WHERE order_id IN (1, 2);那么路由的后果应为: SELECT * FROM t_order_0 WHERE order_id IN (1, 2);SELECT * FROM t_order_1 WHERE order_id IN (1, 2);绑定表的关联查问与单表查问复杂度和性能相当。举例说明,如果一个蕴含绑定表的关联查问的SQL如下: ...

July 22, 2020 · 2 min · jiezi

关于中间件:ShardingSphere-4x-数据分片内核剖析

ShardingSphere的3个产品的数据分片次要流程是完全一致的。外围由SQL解析 => 执行器优化 => SQL路由 => SQL改写 => SQL执行 => 后果归并的流程组成。 SQL解析分为词法解析和语法解析。先通过词法解析器将SQL拆分为一个个不可再分的单词。再应用语法解析器对SQL进行了解,并最终提炼出解析上下文。解析上下文包含表、选择项、排序项、分组项、聚合函数、分页信息、查问条件以及可能须要批改的占位符的标记。 执行器优化合并和优化分片条件,如OR等。 SQL路由依据解析上下文匹配用户配置的分片策略,并生成路由门路。目前反对分片路由和播送路由。 SQL改写将SQL改写为在实在数据库中能够正确执行的语句。SQL改写分为正确性改写和优化改写。 SQL执行通过多线程执行器异步执行。 后果归并将多个执行后果集归并以便于通过对立的JDBC接口输入。后果归并包含流式归并、内存归并和应用装璜者模式的追加归并这几种形式。

July 22, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-数据分片核心概念配置

分片规定分片规定配置的总入口。蕴含数据源配置、表配置、绑定表配置以及读写拆散配置等。 数据源配置实在数据源列表。 表配置逻辑表名称、数据节点与分表规定的配置。 数据节点配置用于配置逻辑表与实在表的映射关系。可分为均匀分布和自定义散布两种模式。 均匀分布指数据表在每个数据源内出现均匀分布的态势,例如: db0 ├── t_order0 └── t_order1 db1 ├── t_order0 └── t_order1那么数据节点的配置如下: db0.t_order0, db0.t_order1, db1.t_order0, db1.t_order1自定义散布指数据表出现有特定规定的散布,例如: db0 ├── t_order0 └── t_order1 db1 ├── t_order2 ├── t_order3 └── t_order4那么数据节点的配置如下: db0.t_order0, db0.t_order1, db1.t_order2, db1.t_order3, db1.t_order4分片策略配置对于分片策略存有数据源分片策略和表分片策略两种维度。 数据源分片策略对应于DatabaseShardingStrategy。用于配置数据被调配的指标数据源。 表分片策略对应于TableShardingStrategy。用于配置数据被调配的指标表,该指标表存在与该数据的指标数据源内。故表分片策略是依赖与数据源分片策略的后果的。 两种策略的API完全相同。 自增主键生成策略通过在客户端生成自增主键替换以数据库原生自增主键的形式,做到分布式主键无反复。

July 22, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-数据分片核心概念SQL

逻辑表程度拆分的数据库(表)的雷同逻辑和数据结构表的总称。例:订单数据依据主键尾数拆分为10张表,别离是t_order_0到t_order_9,他们的逻辑表名为t_order。 实在表在分片的数据库中实在存在的物理表。即上个示例中的t_order_0到t_order_9。 数据节点数据分片的最小单元。由数据源名称和数据表组成,例:ds_0.t_order_0。 绑定表指分片规定统一的主表和子表。例如:t_order表和t_order_item表,均依照order_id分片,则此两张表互为绑定表关系。绑定表之间的多表关联查问不会呈现笛卡尔积关联,关联查问效率将大大晋升。举例说明,如果SQL为: SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);在不配置绑定表关系时,假如分片键

July 22, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-数据分片

背景传统的将数据集中存储至繁多数据节点的解决方案,在性能、可用性和运维老本这三方面曾经难于满足互联网的海量数据场景。 从性能方面来说,因为关系型数据库大多采纳B+树类型的索引,在数据量超过阈值的状况下,索引深度的减少也将使得磁盘拜访的IO次数减少,进而导致查问性能的降落;同时,高并发拜访申请也使得集中式数据库成为零碎的最大瓶颈。 从可用性的方面来讲,服务化的无状态型,可能达到较小老本的随便扩容,这必然导致系统的最终压力都落在数据库之上。而繁多的数据节点,或者简略的主从架构,曾经越来越难以承当。数据库的可用性,已成为整个零碎的要害。 从运维老本方面思考,当一个数据库实例中的数据达到阈值以上,对于DBA的运维压力就会增大。数据备份和复原的工夫老本都将随着数据量的大小而愈发不可控。一般来讲,繁多数据库实例的数据的阈值在1TB之内,是比拟正当的范畴。 在传统的关系型数据库无奈满足互联网场景须要的状况下,将数据存储至原生反对分布式的NoSQL的尝试越来越多。但NoSQL对SQL的不兼容性以及生态圈的不欠缺,使得它们在与关系型数据库的博弈中始终无奈实现致命一击,而关系型数据库的位置却仍然不可撼动。 数据分片指依照某个维度将寄存在繁多数据库中的数据扩散地寄存至多个数据库或表中以达到晋升性能瓶颈以及可用性的成果。数据分片的无效伎俩是对关系型数据库进行分库和分表。分库和分表均能够无效的防止由数据量超过可接受阈值而产生的查问瓶颈。除此之外,分库还可能用于无效的扩散对数据库单点的访问量;分表尽管无奈缓解数据库压力,但却可能提供尽量将分布式事务转化为本地事务的可能,一旦波及到跨库的更新操作,分布式事务往往会使问题变得复杂。应用多主多从的分片形式,能够无效的防止数据单点,从而晋升数据架构的可用性。 通过分库和分表进行数据的拆分来使得各个表的数据量放弃在阈值以下,以及对流量进行疏导应答高访问量,是应答高并发和海量数据系统的无效伎俩。数据分片的拆分形式又分为垂直分片和程度分片。 垂直分片依照业务拆分的形式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用。在拆分之前,一个数据库由多个数据表形成,每个表对应着不同的业务。而拆分之后,则是依照业务将表进行归类,散布到不同的数据库中,从而将压力扩散至不同的数据库。下图展现了依据业务须要,将用户表和订单表垂直分片到不同的数据库的计划。 垂直分片往往须要对架构和设计进行调整。通常来讲,是来不及应答互联网业务需要疾速变动的;而且,它也并无奈真正的解决单点瓶颈。垂直拆分能够缓解数据量和访问量带来的问题,但无奈根治。如果垂直拆分之后,表中的数据量仍然超过单节点所能承载的阈值,则须要程度分片来进一步解决。 程度分片程度分片又称为横向拆分。绝对于垂直分片,它不再将数据依据业务逻辑分类,而是通过某个字段(或某几个字段),依据某种规定将数据扩散至多个库或表中,每个分片仅蕴含数据的一部分。例如:依据主键分片,偶数主键的记录放入0库(或表),奇数主键的记录放入1库(或表),如下图所示。 程度分片从实践上冲破了单机数据量解决的瓶颈,并且扩大绝对自在,是分库分表的规范解决方案。 挑战尽管数据分片解决了性能、可用性以及单点备份复原等问题,但分布式的架构在取得了收益的同时,也引入了新的问题。 面对如此散乱的分库分表之后的数据,利用开发工程师和数据库管理员对数据库的操作变得异样沉重就是其中的重要挑战之一。他们须要晓得数据须要从哪个具体的数据库的分表中获取。 另一个挑战则是,可能正确的运行在单节点数据库中的SQL,在分片之后的数据库中并不一定可能正确运行。例如,分表导致表名称的批改,或者分页、排序、聚合分组等操作的不正确处理。 跨库事务也是分布式的数据库集群要面对的辣手事件。正当采纳分表,能够在升高单表数据量的状况下,尽量应用本地事务,长于应用同库不同表可无效防止分布式事务带来的麻烦。在不能防止跨库事务的场景,有些业务依然须要放弃事务的一致性。而基于XA的分布式事务因为在并发度高的场景中性能无奈满足需要,并未被互联网巨头大规模应用,他们大多采纳最终一致性的柔性事务代替强统一事务。 指标尽量透明化分库分表所带来的影响,让应用方尽量像应用一个数据库一样应用程度分片之后的数据库集群,是ShardingSphere数据分片模块的次要设计指标。

July 22, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-SHARDINGSCALINGALPHA-快速入门

疾速开始部署启动1. 执行以下命令,编译生成sharding-scaling二进制包:git clone https://github.com/apache/shardingsphere.git;cd shardingsphere;mvn clean install -Prelease;公布包所在目录为:/sharding-distribution/sharding-scaling-distribution/target/apache-shardingsphere-${latest.release.version}-sharding-scaling-bin.tar.gz。 2. 解压缩公布包,批改配置文件conf/server.yaml,这里次要批改启动端口,保障不与本机其余端口抵触,其余值放弃默认即可:port: 8888blockQueueSize: 10000pushTimeout: 1000workerThread: 303. 启动sharding-scaling:sh bin/start.sh留神:如果后端连贯MySQL数据库,须要下载MySQL Connector/J,解压缩后,将mysql-connector-java-5.1.47.jar拷贝到${sharding-scaling}lib目录。 4. 查看日志logs/stdout.log,确保启动胜利。创立迁徙工作Sharding-Scaling提供相应的HTTP接口来治理迁徙工作,部署启动胜利后,咱们能够调用相应的接口来启动迁徙工作。 创立迁徙工作: curl -X POST \ http://localhost:8888/shardingscaling/job/start \ -H 'content-type: application/json' \ -d '{ "ruleConfiguration": { "sourceDatasource": "ds_0: !!org.apache.shardingsphere.orchestration.core.configuration.YamlDataSourceConfiguration\n dataSourceClassName: com.zaxxer.hikari.HikariDataSource\n properties:\n jdbcUrl: jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC&useSSL=false\n username: root\n password: '\''123456'\''\n connectionTimeout: 30000\n idleTimeout: 60000\n maxLifetime: 1800000\n maxPoolSize: 50\n minPoolSize: 1\n maintenanceIntervalMilliseconds: 30000\n readOnly: false\n", "sourceRule": "defaultDatabaseStrategy:\n inline:\n algorithmExpression: ds_${user_id % 2}\n shardingColumn: user_id\ntables:\n t1:\n actualDataNodes: ds_0.t1\n keyGenerator:\n column: order_id\n type: SNOWFLAKE\n logicTable: t1\n tableStrategy:\n inline:\n algorithmExpression: t1\n shardingColumn: order_id\n t2:\n actualDataNodes: ds_0.t2\n keyGenerator:\n column: order_item_id\n type: SNOWFLAKE\n logicTable: t2\n tableStrategy:\n inline:\n algorithmExpression: t2\n shardingColumn: order_id\n", "destinationDataSources": { "name": "dt_0", "password": "123456", "url": "jdbc:mysql://127.0.0.1:3306/test2?serverTimezone=UTC&useSSL=false", "username": "root" } }, "jobConfiguration": { "concurrency": 3 }}'留神:上述须要批改ruleConfiguration.sourceDatasource和ruleConfiguration.sourceRule,别离为源端ShardingSphere数据源和数据表规定相干配置; ...

July 22, 2020 · 2 min · jiezi

关于中间件:ShardingSphere-4x-ShardingProxy-快速入门

1. 规定配置编辑%SHARDING_PROXY_HOME%\conf\config-xxx.yaml。详情请参见配置手册。 编辑%SHARDING_PROXY_HOME%\conf\server.yaml。详情请参见配置手册。 2. 引入依赖如果后端连贯PostgreSQL数据库,不须要引入额定依赖。 如果后端连贯MySQL数据库,须要下载MySQL Connector/J,解压缩后,将mysql-connector-java-5.1.47.jar拷贝到${sharding-proxy}lib目录。 3. 启动服务应用默认配置项${sharding-proxy}\bin\start.sh配置端口${sharding-proxy}\bin\start.sh ${port}

July 22, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-ShardingJDBC-快速入门

1. 引入 maven 依赖<dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-jdbc-core</artifactId> <version>${latest.release.version}</version></dependency>留神:请将 ${latest.release.version} 更改为理论的版本号。 2. 规定配置ShardingSphere-JDBC 能够通过 Java,YAML,Spring 命名空间和 Spring Boot Starter 这 4 种形式进行配置,开发者可依据场景抉择适宜的配置形式。详情请参见配置手册。 3. 创立数据源通过 ShardingSphereDataSourceFactory 工厂和规定配置对象获取 ShardingSphereDataSource。该对象实现自 JDBC 的规范 DataSource 接口,可用于原生 JDBC 开发,或应用 JPA, MyBatis 等 ORM 类库。 DataSource dataSource = ShardingSphereDataSourceFactory.createDataSource(dataSourceMap, configurations, properties);

July 22, 2020 · 1 min · jiezi

关于中间件:ShardingSphere-4x-概览

ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(打算中)这3款互相独立的产品组成。 他们均提供标准化的数据分片、分布式事务和数据库治理性能,可实用于如Java同构、异构语言、云原生等各种多样化的利用场景。 ShardingSphere定位为关系型数据库中间件,旨在充沛正当地在分布式的场景下利用关系型数据库的计算和存储能力,而并非实现一个全新的关系型数据库。 它与NoSQL和NewSQL是并存而非互斥的关系。NoSQL和NewSQL作为新技术摸索的前沿,放眼将来,拥抱变动,是十分值得举荐的。反之,也能够用另一种思路对待问题,放眼将来,关注不变的货色,进而抓住事物本质。 关系型数据库当今仍然占有微小市场,是各个公司外围业务的基石,将来也难于撼动,咱们目前阶段更加关注在原有根底上的增量,而非颠覆。 ShardingSphere曾经在2020年4月16日从Apache孵化器毕业,成为Apache顶级我的项目。 欢送通过shardingsphere的dev邮件列表与咱们探讨。 简介Sharding-JDBC 定位为轻量级Java框架,在Java的JDBC层提供的额定服务。 它应用客户端直连数据库,以jar包模式提供服务,无需额定部署和依赖,可了解为增强版的JDBC驱动,齐全兼容JDBC和各种ORM框架。 实用于任何基于JDBC的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或间接应用JDBC。反对任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。反对任意实现JDBC标准的数据库。目前反对MySQL,Oracle,SQLServer,PostgreSQL以及任何遵循SQL92规范的数据库。 Sharding-Proxy 定位为透明化的数据库代理端,提供封装了数据库二进制协定的服务端版本,用于实现对异构语言的反对。 目前先提供MySQL/PostgreSQL版本,它能够应用任何兼容MySQL/PostgreSQL协定的拜访客户端(如:MySQL Command Client, MySQL Workbench, Navicat等)操作数据,对DBA更加敌对。 向应用程序齐全通明,可间接当做MySQL/PostgreSQL应用。实用于任何兼容MySQL/PostgreSQL协定的的客户端。 Sharding-Sidecar(TODO) 定位为Kubernetes的云原生数据库代理,以Sidecar的模式代理所有对数据库的拜访。 通过无核心、零侵入的计划提供与数据库交互的的啮合层,即Database Mesh,又可称数据网格。 Database Mesh的关注重点在于如何将分布式的数据拜访利用与数据库有机串联起来,它更加关注的是交互,是将横七竖八的利用与数据库之间的交互无效的梳理。应用Database Mesh,拜访数据库的利用和数据库终将造成一个微小的网格体系,利用和数据库只需在网格体系中对号入座即可,它们都是被啮合层所治理的对象。 混合架构 Sharding-JDBC采纳无中心化架构,实用于Java开发的高性能的轻量级OLTP利用;Sharding-Proxy提供动态入口以及异构语言的反对,实用于OLAP利用以及对分片数据库进行治理和运维的场景。 ShardingSphere是多接入端独特组成的生态圈。 通过混合应用Sharding-JDBC和Sharding-Proxy,并采纳同一注册核心对立配置分片策略,可能灵便的搭建实用于各种场景的利用零碎,架构师能够更加自在的调整适宜于以后业务的最佳零碎架构。 性能列表数据分片 分库 & 分表读写拆散分片策略定制化无中心化分布式主键分布式事务 标准化事务接口XA强统一事务柔性事务数据库治理 配置动态化编排 & 治理数据脱敏可视化链路追踪弹性伸缩(布局中)我的项目状态

July 22, 2020 · 1 min · jiezi

DAS之DAS-Console应用实践

作者:王亮 卢声远 DAS是信也科技自研的数据库拜访框架。它包含数据库控制台das console,数据库客户端das client和数据库服务端das server三局部。DAS是基于Java语言开发的,反对数据库治理,ORM,SQL创立,分库分表操作的一体化数据库拜访解决方案。DAS我的项目从去年开始曾经在GitHub上开源:https://github.com/ppdaicorp/das 作为控制台的das console模块实现了DAS的配置,治理和各种辅助工具的需要。还等什么呢,让咱们直奔主题开启das console之旅! DAS-Console简介DAS-Console是信业科技自研的数据库拜访中间件DAS的web控制台,不便的DAS数据库配置管理和代码生成工具。 DAS-Console 产品定位通过DAS-Console去管制物理库信息,逻辑库,分库分表策略,MGR等配置。开发业务逻辑时间接撸dao代码,其余一律不必管,进而实现配置和理论的DAO代码开发拆散,让开发人员集中精力在业务逻辑上。 DAS-Console 根本特点集成配置核心,同步数据校验跨环境同步数据,原子操作,不便局部更新代码转换,mybatis mapper 转换das code动静策略,依据自定义java代码加载数据查问,反对分库查问DAS-console数据模型DAS操作的对象次要是DAS的数据模型,那么咱们来看一下DAS的次要数据模型:外围的模型是application,logic database, physical database,三者为多对多的关系,以及为了方便管理的分组DAS team的概念。 以及其余的全局配置项:data source configuration。 数据模型关系如图所示:咱们把这些数据模型在Apollo下面的存储模式介绍一下: application 咱们将利用的配置信息(次要是这个利用用到的logic database的id)放在利用各自Apollo外面,用独立的namespace寄存,防止与利用其余配置相互影响。logic database 它次要是它和physical database的关联关系,以及分库分表的配置信息。 因为它的信息对利用来说是没必要裸露的,所以咱们把logic database信息集中在一个Apollo利用上面。咱们利用namespace的性能,将同team的logic database组织在一个namespace里。physical database它次要存储物理库的域名,端口,用户名,明码等信息。因为这些信息比拟敏感,间接寄存Apollo是不平安的。于是咱们将寄存物理数据库信息的性能放在了一个服务中,下一个章节咱们专门来介绍一下这个集成点。data source configuration 这块存储数据库连接池的配置信息,譬如连接池大小,过期工夫等等。DAS-Console 代码转换问题背景对于一些曾经应用了mybatis的我的项目,曾经有了mapper配置文件,如果接入das须要从新配置。 解决方案针对这个问题,咱们设计和开发了mybatis mapper 转换das code的性能,用户能够不便的把mybatis的mapper转换成das的配置。 DAS-Console 动静策略,自定义JAVA代码加载问题背景对于区别于个别通的业务场景,用户须要依据理论状况自定义非凡的分库分表策略。 解决方案能够应用动静策略,通过配置的形式,应用JAVA代码自定义就能够不便的实现各种非凡须要 DAS-Console 数据查问,反对分库分表查问问题背景对于接入了das的我的项目,有的我的项目应用的分库分表的性能,如果须要进行数据查问的话,分库分表间接查问物理库很不不便 。 解决方案应用das的查问工具,能够依据逻辑库的维度去查问。 介绍完das的根本特点,曾经接入了das的小伙伴们示意、、、 DAS-Console 适配配置核心每个零碎都须要有本人的配置信息configuration,或者叫元信息metadata。DAS的配置信息次要是物理数据库信息,逻辑数据库和利用等。 在原生开源DAS的实现外面,DAS是利用本地XML文件作为这些信息的存储。然而作为企业的利用,本地文本配置的形式是不适宜的。从cloud native的角度来说,配置应该和代码严格拆散,这对满足利用部署到多环境来说是很重要的。 拍拍贷外部应用Apollo来做配置核心,这是一款业内比拟风行的分布式配置核心,十分符合分布式和微服务的配置管理场景,而且拍拍贷对Apollo的应用和运维也积攒了不少教训。因而咱们决定利用Apollo作为DAS的配置核心。 从配置的具体操作来讲,无外乎读配置和写配置这两大性能。DAS client须要从Apollo读配置,DAS console作为一个治理portal要去写配置。 DAS client的读Apollo操作利用了Apollo的client API读取物理数据库信息,逻辑数据库和利用等等。用Apollo的client API来读配置,就必然会引起代码改变,那么DAS是如何优雅地实现Apollo配置的读取呢?答案就是:ClientConfigureLoader接口的设计。 ClientConfigureLoader接口中最重要的办法就是DasConfigure load()。 开源ClientConfigureLoader的实现:基于的是XML文件的解析。拍拍贷ClientConfigureLoader的实现:基于Apollo的client API的实现。这里具体介绍的是DAS解耦配置实现的做法,DAS利用对ClientConfigureLoader接口实现了获取配置与应用配置的解耦。 那么DAS是如何加载不同的ClientConfigureLoader接口实现呢?答案就是利用java的Service Loader SPI的机制。 ...

July 15, 2020 · 1 min · jiezi

敏捷数据计算中间件

【摘要】计算中间件是应用与数据之间,独立进行计算的可编程通用软件,常用以解决松耦合、高性能、特殊源计算、多源混算、复杂逻辑等问题。但传统计算中间件一般用硬编码实现,不仅开发效率低、维护难度大,而且在数据、算法与应用之间存在强耦合性,有时还会对数据库造成不必要的压力。如何用敏捷数据计算中间件解决此类顽疾?请移步敏捷数据计算中间件。下载全文 ...

June 28, 2020 · 1 min · jiezi

单机和分布式场景下有哪些流控方案

简介: 不同的场景下所需的流控算法不尽相同,那应该如何选择适用的流控方案呢?本文分享单机及分布式流控场景下,简单窗口、滑动窗口、漏桶、令牌桶、滑动日志等几种流控算法的思路和代码实现,并总结了各自的复杂度和适用场景。较长,同学们可收藏后再看。 一 流控的场景流控的意义其实无需多言了。最常用的场景下,流控是为了保护下游有限的资源不被流量冲垮,保证服务的可用性,一般允许流控的阈值有一定的弹性,偶尔的超量访问是可以接受的。 有的时候,流控服务于收费模式,比如某些云厂商会对调用 API 的频次进行计费。既然涉及到钱,一般就不允许有超出阈值的调用量。 这些不同的场景下,适用的流控算法不尽相同。大多数情况下,使用 Sentinel 中间件已经能很好地应对,但 Sentinel 也并不是万能的,需要思考其他的流控方案。 二 接口定义为了方便,以下所有的示例代码实现都是基于 Throttler 接口。 Throttler 接口定义了一个通用的方法用于申请单个配额。 当然你也可以定义一个 tryAcquire(String key, int permits) 签名的方法用于一次申请多个配额,实现的思路是一样的。 有些流控算法需要为每个 key 维护一个 Throttler 实例。 public interface Throttler { /** * 尝试申请一个配额 * * @param key 申请配额的key * @return 申请成功则返回true,否则返回false */ boolean tryAcquire(String key);}三 单机流控1 简单窗口简单窗口是我自己的命名,有些地方也叫做固定窗口,主要是为了跟后面的滑动窗口区分。流控是为了限制指定时间间隔内能够允许的访问量,因此,最直观的思路就是基于一个给定的时间窗口,维护一个计数器用于统计访问次数,然后实现以下规则: 如果访问次数小于阈值,则代表允许访问,访问次数 +1。如果访问次数超出阈值,则限制访问,访问次数不增。如果超过了时间窗口,计数器清零,并重置清零后的首次成功访问时间为当前时间。这样就确保计数器统计的是最近一个窗口的访问量。代码实现 SimpleWindowThrottler /** * 毫秒为单位的时间窗口 */private final long windowInMs;/** * 时间窗口内最大允许的阈值 */private final int threshold;/** * 最后一次成功请求时间 */private long lastReqTime = System.currentTimeMillis();/** * 计数器 */private long counter;public boolean tryAcquire(String key) { long now = System.currentTimeMillis(); // 如果当前时间已经超过了上一次访问时间开始的时间窗口,重置计数器,以当前时间作为新窗口的起始值 if (now - lastReqTime > windowInMs) { #1 counter = 0; lastReqTime = now; #2 } if (counter < threshold) { #3 counter++; #4 return true; } else { return false; }}另外一种常见的场景是根据不同的 key 来做流控,每个 key 有单独的时间窗口、阈值配置,因此需要为每个 key 维护一个单独的限流器实例。 ...

June 24, 2020 · 7 min · jiezi

首个系统化学习ShardingSphere的课程上线

ShardingSphere 历时 523 天顺利毕业,成为 Apache 顶级项目,并且是业内首个 Apache 分布式数据库中间件项目,这样的成就得益于社区的努力。各位贡献者的开源精神和技术探索,帮助 ShardingSphere 不断成长。 未来 ShardingSphere 的落地,同样少不了技术人员的使用与推广。 一路走来,有很多朋友在推动 ShardingSphere 的落地。比如拉勾旗下的拉勾教育,最近更是上线了一门《ShardingSphere 核心原理精讲》专栏,希望帮你掌握分库分表技巧,提升海量数据处理技术,这也是首个系统化学习 ShardingSphere 的课程! 原价98元,拉勾教育提供学费补贴, 现在订阅仅需1元,并且可以永久收看。 张亮力荐 Apache ShardingSphere Founder &amp;amp; VP 张亮倾力推荐「 ShardingSphere 核心原理精讲」 内容解读本专栏共 6 大模块,34讲内容,为你介绍主流分库分表解决方案和工程实践,带你掌握 ShardingSphere 核心功能和实现原理,基于 ShardingSphere 开源框架源码剖析,提高通用底层原理的理解力,提升实际场景开发能力。 1.了解分库分表的应用方式和实现原理帮你理解 ShardingSphere 的核心特性,来满足日常开发工作所需。基于源码给出基础设施、分片引擎、分布式事务和治理与集成等等这些功能的设计原理和实现机制。课程配套代码,你可以在专栏的内容中找到下载链接。 2.学习优秀的开源框架,提高技术理解与应用能力技术原理是具有相通性的。通过对开源框架(如 ZooKeeper、Nacos、Seata )的解读,强化你对技术体系的系统化理解,还可以让你掌握这些技术体系的具体应用场景和实现方式,从而实现触类旁通。 3.学习从源码分析到日常开发的技巧在理解 ShardingSphere 的同时,带你提炼出包括:设计模式的应用(如工厂模式、策略模式、模板方法等)、微内核架构等架构模式、组件设计和类层结构划分的思想和实现策略、常见缓存的应用以及自定义缓存机制的实现、Spring 家族框架的集成和整合等开发技巧,这些开发技巧都能够直接应用到日常开发过程。 下面是课程的目录,一定对你很有帮助 限时福利: 原价98元,拉勾教育致力于 ShardingSphere 推广,提供了学费补贴 现 1 元即可订阅 识别下图二维码,即可订阅

June 17, 2020 · 1 min · jiezi

SpringBoot分布式任务中间件开发-附视频讲解-手把手教你开发和使用中间件

作者:小傅哥博客:https://bugstack.cn 沉淀、分享、成长,让自己和他人都能有所收获!?分布式任务DcsSchedule中间件,Github地址:https://github.com/fuzhengwei/schedule-spring-boot-starter分布式任务DcsSchedule控制台,Github地址:https://github.com/fuzhengwei/itstack-middleware-control演示视频前言@SpringBootApplication@EnableSchedulingpublic class Application{ public static void mian(String[] args){ SpringApplication.run(Application.class,args); } @Scheduled(cron = "0/3 * * * * *") public void demoTask() { //... }}咔咔,上面这段代码很熟悉吧,他就是SpringBoot的Schedule定时任务,简单易用。在我们开发中如果需要做一些定时或指定时刻循环执行逻辑时候,基本都会使用到Schedule。 但是,如果我们的任务是比较大型的,比如;定时跑批T+1结算、商品秒杀前状态变更、刷新数据预热到缓存等等,这些定时任务都相同的特点;作业量大、实时性强、可用率高。而这时候如果只是单纯使用Schedule就显得不足以控制。 那么,我们产品需求就出来了,分布式DcsSchedule任务; 多机器部署任务统一控制中心启停宕机灾备,自动启动执行实时检测任务执行信息:部署数量、任务总量、成功次数、失败次数、执行耗时等嗯?有人憋半天了想说可以用Quertz,嗯可以的,但这不是本篇文章的重点。难道你不想看看一个自言开源中间件是怎么诞生的吗,怎么推到中心Maven仓的吗?比如下图;真香不! 首页监控任务列表 ?好了,接下来开始介绍这个中间件如何使用和怎么开发的了! 中间件使用1. 版本记录 版本发布日期备注11.0.0-RELEASE2019-12-07基本功能实现;任务接入、分布式启停21.0.1-RELEASE2019-12-07上传测试版本2. 环境准备jdk1.8StringBoot 2.x配置中心zookeeper 3.4.14 {准备好zookeeper服务,如果windows调试可以从这里下载:https://www-eu.apache.org/dis...} 下载后解压,在bin同级路径创建文件夹data、logs修改conf/zoo.cfg,修改配置如下; dataDir=D:\\Program Files\\apache-zookeeper-3.4.14\\datadataLogDir=D:\\Program Files\\apache-zookeeper-3.4.14\\logs打包部署控制平台 下载地址:https://github.com/fuzhengwei...部署访问:http://localhost:73973. 配置POM<dependency> <groupId>org.itstack.middleware</groupId> <artifactId>schedule-spring-boot-starter</artifactId> <version>1.0.0-RELEASE</version></dependency>4. 引入分布式任务DcsSchedule @EnableDcsScheduling与SpringBoot的Sceduling非常像,他的注解是;@EnableScheduling,尽可能降低使用难度这个注解主要方便给我们自己的中间件一个入口,也是?扒拉源码发现的可以这么干{我一直说好的代码都很骚气}@SpringBootApplication@EnableDcsSchedulingpublic class HelloWorldApplication { public static void main(String[] args) { SpringApplication.run(HelloWorldApplication.class, args); }}5. 在任务方法上添加注解这个注解也和SpringBoot的Schedule很像,但是多了desc描述和启停初始化控制cron:执行计划desc:任务描述autoStartup:默认启动状态如果你的任务需要参数可以通过引入service去调用获取等方式都可以@Component("demoTaskThree")public class DemoTaskThree { @DcsScheduled(cron = "0 0 9,13 * * *", desc = "03定时任务执行测试:taskMethod01", autoStartup = false) public void taskMethod01() { System.out.println("03定时任务执行测试:taskMethod01"); } @DcsScheduled(cron = "0 0/30 8-10 * * *", desc = "03定时任务执行测试:taskMethod02", autoStartup = false) public void taskMethod02() { System.out.println("03定时任务执行测试:taskMethod02"); }}6. 启动验证启动SpringBoot工程即可,autoStartup = true的会自动启动任务(任务是多线程并行执行的)启动控制平台:itstack-middleware-control,访问:http://localhost:7397/ 成功界面如下;可以开启/关闭验证了!{功能还在完善}中间件开发以SpringBoot为基础开发一款中间件我也是第一次,因为接触SpringBoot也刚刚1个月左右。虽然SpringBoot已经出来挺久的了,但由于我们项目开发并不使用SpringBoot的一套东西,所以一直依赖没有接触。直到上个月开始考虑领域驱动设计才接触,嗯!真的不错,那么就开始了夯实技能、学习思想用到项目里。 ...

June 11, 2020 · 4 min · jiezi

蚂蚁金服-Service-Mesh-深度实践

作者丨敖小剑 2019 年,蚂蚁金服在 Service Mesh 领域继续高歌猛进,进入大规模落地的深水区。本文介绍了 Service Mesh 在蚂蚁金服的落地情况和即将来临的双十一大考,以及大规模落地时遇到的困难和解决方案,助你了解 Service Mesh 的未来发展方向和前景。 一、前言大家好,我是敖小剑,来自蚂蚁金服中间件团队,今天带来的主题是“诗和远方:蚂蚁金服 Service Mesh 深度实践”。在过去两年,我先后做过两次 Service Mesh 的演讲: 2017 年,当时 Service Mesh 在国内还属于蛮荒时代,我当时做了一个名为“Service Mesh: 下一代微服务”的演讲,开始在国内布道 Service Mesh 技术;2018 年,做了名为“长路漫漫踏歌而行:蚂蚁金服 Service Mesh 实践探索”的演讲,介绍蚂蚁金服在 Service Mesh 领域的探索性的实践,当时蚂蚁金服刚开始在 Service Mesh 探索。今天,有幸第三次,给大家带来的依然是蚂蚁金服在 Service Mesh 领域的实践分享。和去年不同的是,今年蚂蚁金服进入了 Service Mesh 落地的深水区,规模巨大,而且即将迎来双十一大促考验。 <u>备注:现场做了一个调研,了解听众对 Servicve Mesh 的了解程度,结果不太理想:在此之前对 Service Mesh 有了解的同学目测只有 10% 多点(肯定不到 20%)。Service Mesh 的技术布道,依然任重道远。</u> 今天给大家带来的内容主要有三块: 蚂蚁金服落地情况介绍:包括大家最关心的双十一落地情况;大规模落地的困难和挑战:分享一下我们过去一年中在大规模落地上遇到的问题;是否采用 Service Mesh 的建议:这个问题经常被人问起,所以借这个机会给出一些中肯的建议供大家参考。二、蚂蚁金服落地情况介绍(一)发展历程和落地规模 Service Mesh 技术在蚂蚁金服的落地,先后经历过如下几个阶段: ...

November 5, 2019 · 6 min · jiezi

微服务架构案例04中间件集成公共服务封装

本文源码:GitHub·点这里 || GitEE·点这里 更新进度(共6节): 01:项目技术选型简介,架构图解说明02:业务架构设计,系统分层管理03:数据库选型,业务数据设计规划04:中间件集成,公共服务管理一、中间件简介中间件是基础软件的一类, 属于复用性极高的软件。处于操作系统软件与应用程序的之间。是一种独立的系统软件,也可以是公共的服务程序,分布式架构系统借助中间件,可以在不同的技术之间共享资源,或者不同的服务直接传递信息。中间件位操作系统之上,管理计算机资源和网络通讯。是连接两个独立应用程序或独立系统的软件,例如:消息队列中间件,在两个服务之间进行异步的消息传递;数据缓存中间件,缓存整合系统的热点数据,提高程序的响应速度;Nginx中间件,提供负载均衡,服务代理,等功能;二、公共服务简介公共服务,顾名思义就是系统内通用的服务,例如用户身份验证,消息发送,监控预警,网关服务等。 该案例的中间件和公共服务,都是基于Feign接口统一的方式提供服务。 三、中间件集成1、消息中间件RocketMq简介RocketMq 是一款分布式、队列模型的消息中间件,有两个核心角色:消息生产者和消息消费者。作为高并发系统的核心组件之一,能够帮助业务系统解构提高系统稳定性。 应用流程消息生产者@Componentpublic class MsgSendService { @Resource private ProducerConfig producerConfig ; public void sendMsg (MsgWrap msgWrap) { producerConfig.sendMsg(msgWrap.getGroup(),msgWrap.getTopic(), msgWrap.getTag(),msgWrap.getContent()); }}消息消费者@Component@Consumer(group = MsgRoute.husky_group_1, topic = MsgRoute.husky_topic_1 , tag = MsgRoute.husky_tag_1)public class UserSearchListener implements MsgReadService { @Resource private BookEsAnalyFeign bookEsAnalyFeign ; @Override public void readMsg(String msg) throws Exception { LOGGER.info("【用户搜索消息监听 Msg】:{}",msg) ; // 转发请求数据分析服务 bookEsAnalyFeign.sendBookEsMsg(msg); }}提供Feign接口@RestControllerpublic class UserSearchController implements UserSearchFeign { @Resource private SendMsgService sendMsgService ; @Override public void sendBookSearch(String msgContent) { MsgWrap msgWrap = new MsgWrap() ; msgWrap.setContent(msgContent); msgWrap.setGroup(MsgRoute.husky_group_1); msgWrap.setTopic(MsgRoute.husky_topic_1); msgWrap.setTag(MsgRoute.husky_tag_1); sendMsgService.sendMsg(msgWrap); }}2、缓存中间件Redis简介Redis 是一个基于内存的高性能key-value数据库。对高并发系统提供各种场景的支撑:热点数据缓存,计数器,流量削峰等。 ...

November 5, 2019 · 3 min · jiezi

Redis-Streams与Spark的完美结合

来源:Redislabs作者:Roshan Kumar翻译:Kevin  (公众号:中间件小哥) 最近,我有幸在 Spark +AI 峰会上发表了题目为“Redis + Structured Streaming:扩展您的持续应用的完美组合”的演讲。 我对这个主题的兴趣是由 Apache Spark 和 Redis 在过去几个月中引入的新功能引起的。根据我之前使用 Apache Spark 的经验,我很欣赏它在运行批处理时的优雅,并且它在 2.0 版本中引入 Structured Streaming 是在这个方向上的进一步发展。 与此同时,Redis 最近宣布了用于管理流数据的新数据结构,称为“Streams”。Redis Streams 提供了生产者和消费者之间的异步通信功能以及持久性、回顾性查询功能和类似于 Apache Kafka 的横向扩展选项。从本质上讲,Redis 通过Streams 提供了一个轻便、快速、易于管理的流数据库,使数据工程师们受益良多。 此外,开发 Spark-Redis 库是为了使 Redis 可以作为弹性分布式数据集(RDD)使用。因为现在有了 Structured Streaming 和 Redis Streams,我们决定扩展 Spark-Redis 库将 Redis Streams 集成为 Apache Spark Structured Streaming 的数据源。 在上个月的演讲中,我演示了如何在 Redis Streams 中收集用户活动数据并将其下载到 Apache Spark 进行实时数据分析。我开发了一个小型的适合移动设备的 Node.js 应用程序,在这个程序中人们可以点击投票给他们最喜欢的狗来进行有趣的比赛。 这是一场艰苦的战斗,有几个观众甚至是黑客很有创意地攻击了我的应用程序。他们使用“页面检查”选项更改了 HTML 按钮名称试图弄乱应用的显示。但最终他们失败了,因为 Redis Streams,Apache Spark,Spark-Redis 库和我的代码都足够的强大,可以有效地应对这些攻击。 ...

October 17, 2019 · 1 min · jiezi

RocketMQ主从同步源码分析

微信公众号「后端进阶」,专注后端技术分享:Java、Golang、WEB框架、分布式中间件、服务治理等等。之前写了一篇关于 RocketMQ 队列与 Kafka 分区副本的区别文章,里面提到了 RocketMQ 的消息冗余主要是通过主备同步机制实现的,这跟 Kafka 分区副本的 Leader-Follower 模型不同,HA(High Available) 指的是高可用性,而 RocketMQ 的HA机制是通过主备同步实现消息的高可用。 HA 核心类HA 的实现逻辑放在了 store 存储模块的ha目录中,其核心实现类如下: HAService:主从同步的核心实现类HAService$AcceptSocketService:主服务器监听从服务器连接实现类HAService$GroupTransferService:主从同步通知类,实现同步复制和异步复制的功能HAService$HAClient:从服务器连接主服务实现类HAConnection:主服务端 HA 连接对象的封装,当主服务器接收到从服务器发过来的消息后,会封装成一个 HAConnection 对象,其中里面又封装了读 Socket 连接实现与 写 Socket 连接实现:HAConnection$ReadSocketService:主服务器读实现类HAConnection$WriteSocketService:主服务器写实现类RocketMQ 主从同步的整体工作机制大致是: 从服务器主动建立 TCP 连接主服务器,然后每隔 5s 向主服务器发送 commitLog 文件最大偏移量拉取还未同步的消息;主服务器开启监听端口,监听从服务器发送过来的信息,主服务器收到从服务器发过来的偏移量进行解析,并返回查找出未同步的消息给从服务器;客户端收到主服务器的消息后,将这批消息写入 commitLog 文件中,然后更新 commitLog 拉取偏移量,接着继续向主服务拉取未同步的消息。Slave -> Master 过程从 HA 实现逻辑可看出,可大致分为两个过程,分别是从服务器上报偏移量,以及主服务器发送未同步消息到从服务器。 从上面的实现类可知,从服务器向主服务器上报偏移量的逻辑在 HAClient 类中,HAClient 类是一个继承了 ServiceThread 类,即它是一个线程服务类,在 Broker 启动后,Broker 启动开一条线程定时执行从服务器上报偏移量到主服务器的任务。 org.apache.rocketmq.store.ha.HAService.HAClient#run: public void run() { log.info(this.getServiceName() + " service started"); while (!this.isStopped()) { try { // 主动连接主服务器,获取socketChannel对象 if (this.connectMaster()) { if (this.isTimeToReportOffset()) { // 执行上报偏移量到主服务器 boolean result = this.reportSlaveMaxOffset(this.currentReportedOffset); if (!result) { this.closeMaster(); } } // 每隔一秒钟轮询一遍 this.selector.select(1000); // 处理主服务器发送过来的消息 boolean ok = this.processReadEvent(); if (!ok) { this.closeMaster(); } // ...... } else { this.waitForRunning(1000 * 5); } } catch (Exception e) { log.warn(this.getServiceName() + " service has exception. ", e); this.waitForRunning(1000 * 5); } } log.info(this.getServiceName() + " service end");}以上是 HAClient 线程 run 方法逻辑,主要是做了主动连接主服务器,并上报偏移量到主服务器,以及处理主服务器发送过来的消息,并不断循环执行以上逻辑。 ...

October 14, 2019 · 5 min · jiezi

阿里张磊云计算生态价值点正迅速聚焦到应用上

导读:云原生不再只是基础设施的开发和运维人员的关注点,在应用交付领域小组成立之后,CNCF 基金会正在同应用开发和应用运维人员更紧密的联系在一起。云原生的理念如今正如火如荼。它不仅仅是一种技术,更是社区基于对云的思考,逐渐提炼出的一系列技术、最佳实践与方法论的集合。不过,到目前为止云原生的讨论较多局限在基础设施的开发和运维人员群体中。 相比之下,更关注业务本身的应用开发同学,与云原生技术带来的资源利用率提升、分布式系统的弹性扩展与可靠性等能力之间,始终存在着一定的隔阂。对这部分同学来说,云原生技术更多时候还停留在“知其然”的阶段。 然而,伴随着云原应用的理念持续普及,我们正看到整个云计算生态的核心关注点正在发生着微妙的变化。 2019 年 9 月 12 日,云原生基金会 CNCF 宣布成立应用交付领域小组(Application Delivery SIG)。阿里巴巴高级技术专家、Kubernetes 社区资深成员张磊,软件智能公司 Dynatrace 的首席技术与战略创新官 Alois Reitbauer,与 VMware 资深专家 Bryan Liles 共同当选为该小组首届联席主席。 该领域小组是 CNCF 基金会官方成立的第一个以“应用”为中心的领域小组,也被社区誉为是 “CNCF 里最具价值的领域小组”。 那么,为什么 CNCF 会将“应用交付”设立为新的核心关注点呢?云原生的本质,是一种让应用最大程度享受云计算红利的架构思想。这种思想,实际上是在云计算技术不断普及的过程中,应用基础架构不断朝着”让专业的人做专业事“的方向持续演进、然后逐步沉淀下来的一套最佳实践和架构范式。 实际上,在云计算真正普及之前,基础设施能力(比如服务发现、流量控制、监控与可观测性、访问控制、网络控制、存储层抽象等)并不是开发者唾手可得的资源。所以应用基础设施必须以某种方式屏蔽底层基础设施对它的缺失和薄弱的环节进行增补,才能够让开发者更好的专注于业务逻辑这个最具价值的事情。 所以在这个时期,传统应用基础架构与应用之间是非常紧密的耦合关系,要么应用基础设施直接接管应用开发本身的各个阶段(比如 ESB),要么就是应用基础设施直接成为应用开发过程中的一部分(比如 各种编程框架和中间件)。这种架构下,应用本身的能力与演进,实际上是跟应用基础设施的命运被紧紧的绑定在了一起。 当然,这个情况如今已经今非昔比。云计算的迅速崛起,使得当今的基础设施能力正逐渐通过 Kubernetes 这样的标准的平台层下沉到了更加专业的云服务体系当中,而不再拘泥和锁定于传统中心化应用基础设施和中间件自身的能力。云原生技术体系,打通了云与应用之间最后的隔阂,也使得后续涌现出的 Service Mesh 思想得以进一步解耦“应用”与“应用基础设施”,使得应用可以直接通过 localhost,即可连接到原先必须由中心化应用基础设施或者中间件才能提供的各项能力当中。 伴随着云原生应用架构的逐步落地,应用开发者的心智正逐步从基础设施层当中解放出来。这也使得社区的价值聚焦点,开始从“资源效能”逐步向“研发效能”和“交付效能”靠拢。这个变化,将会接下来成为云原生生态继续发展的一个重要趋势。 如何解读云原生基金会 CNCF 成立应用交付领域小组?对于这一新成立的领域小组,其后续会做哪些事情是广大云计算领域开发者非常关注的,张磊表示: 一、领域小组将逐步确立和推进“云原生应用管理与标准交付体系”云原生应用管理与交付是一个随着云原生技术日渐成熟之后迅速成为新一代云计算技术聚焦点的重要技术领域。在当前的技术生态当中,Kubernetes 正在构建一个受到全世界普遍认同的、标准化的应用基础设施层;Serverless 则提供了一种高效的调度与资源管理模型;而 Service Mesh 则进一步明确了应用之间非侵入式的服务治理机制。这些能力,我们都统一称之为“平台层能力”,也是之前 CNCF 基金会主要关注的领域。 而本次 CNCF 应用交付领域小组所关注的,则是在“平台层”之上的“应用管理层”的技术架构和演进方向。这一层,也是未来云计算生态的价值聚焦点。 应用交付领域小组将致力于与整个云原生社区协作,共同在“应用”、“最终用户”和“平台层”之间,构建出一套高效、标准和可信赖的交付与连通体系。这个思想贯穿应用交付的声明周期,我们可以通过一个标准的分层结构(云原生应用分层模型)来将其形象表达出来: 在这个模型下,“应用定义”,“应用部署与交付”,和“应用实例管理”之间会进行清晰的分层和协作。这种分层理念,是目前整个云计算生态都缺失的。而云原生应用分层模型,将会成为后续云原生应用交付生态向“标准化”、“插件化”、和“职责分离”的方向不断演进的重要理论基础。 二、云原生应用交付最佳实践与架构范式应用交付领域小组将协同云原生开源社区一起,在上述“云原生应用分层模型”体系下逐步抽象与提炼出各层对应的最佳实践、基础范式、参考架构与项目范例,同时对主流开源社区中的应用管理项目进行梳理和汇总。最终,这些内容都会以《CNCF 云原生应用架构白皮书》的方式同整个生态见面。 三、推动云原生应用交付生态向分层与标准的架构上不断演进在上述理论和实践基础上,应用交付领域小组将会联同社区和生态,共同推进主线应用管理开源项目逐步向分层、统一、标准的方向持续演进。此外,领域小组也会持续在这套体系下进一步甄别和孵化开源项目,并通过编制《云原生应用交付生态指南(Cloud Native App Delivery Lanscape)》来帮助云原生用户和开发者进行选型和架构参考。这些都有望让云原生社区的终端用户真正成为应用交付领域小组最大的受益者。 ...

October 9, 2019 · 1 min · jiezi

SOFAEnclave蚂蚁金服新一代可信编程环境让机密计算为金融业务保驾护航102年

作者 | 闫守孟、肖俊贤、田洪亮 近日,Linux 基金会宣布全球多家巨头企业成立机密计算联盟(Confidential Computing Consortium),在对于数据安全和隐私担忧的不断增长下,基于可信执行环境技术的机密计算作为一种可行的解决方案,成为互联网巨头关注的焦点。蚂蚁金服很早就关注此类技术,并基于机密计算打造了蚂蚁金服新一代可信编程中间件 SOFAEnclave,为金融业务保驾护航。机密计算是蚂蚁安全计算的一环,也是金融级云原生的一块重要版图,蚂蚁金服表示:相信未来机密计算将和 HTTPS 一样,成为云计算的标配。引言互联网金融本质上是对大量敏感数据的处理以及由此沉淀的关键业务智能。近年来涌现出来的新业态更是将数据处理的范畴从单方数据扩展到了涉及合作方的多方数据。 另一方面,从 GDPR 到 HIPAA,数据隐私监管保护的范围愈加扩大,力度日益增强。可见,对金融数据和关键业务智能的安全保护,不仅是互联网金融业务的基础,也是其创新发展的依托,更是攸关合规的关键因素。 近年来迅速发展的机密计算技术是一种创新的数据隔离和加密处理技术,其重要特点是,TCB(trusted computing base 可信计算基) 中仅包含应用自身和基础硬件,即使 OS kernel、Hypervisor、甚至 BIOS 等特权软件都已经遭到破坏甚至本来就是恶意的,敏感数据和代码依然能安全无虞。 蚂蚁金服在自身的实践过程中,基于机密计算底层技术发展出金融级的机密计算中间件,确保金融应用数据和代码的机密性和完整性,为关键业务提供易用、安全、集群化的计算环境。 本文从机密计算的技术背景、关键问题、蚂蚁的技术突破、以及典型应用场景等方面展开。 机密计算的技术背景随着云计算的快速发展,越来越多的关键性服务和高价值数据被迁移到了云端。云安全也因此成为学术界和工业界关注的一个焦点。 近年来,云安全领域最重要的一项技术进展名为机密计算(Confidential Computing)。机密计算填补了当前云安全的一项空白——使用中数据(Data-in-use)的加密。过去通行的做法是对数据在存储中(比如硬盘)和传输中(比如网络)加密,而在使用中(比如内存)解密,以便处理。而机密计算可以保护使用中数据的机密性和完整性。 目前,多家云计算巨头都在不约而同地推广这项技术:微软已于 2017 年 7 月宣布开始接受 Azure 机密计算的早期试用申请;IBM 于 2017 年 12 月宣布 IBM 云数据保护(Cloud Data Guard)的预览版;谷歌也于 2018 年 5 月开源了名为 Asylo 的机密计算框架。 那么,机密计算究竟是如何实现的呢? 实际上,上述所有云计算巨头在实现机密计算时都离不开一种称为“可信执行环境(TEE)”的技术。 顾名思义,TEE 提供一种与不可信环境隔离的安全计算环境,正是这种隔离和可信验证机制使得机密计算成为可能。 TEE 一般是直接基于硬件实现的,比如 Intel SGX,AMD SEV,ARM TrustZone,以及 RISC-V Keystone 等;基于虚拟化技术也可以构造 TEE,比如微软的 VSM,Intel 的 Trusty for iKGT & ACRN,但尚不能匹敌硬件 TEE 的安全性。 ...

September 30, 2019 · 3 min · jiezi

Redis-的-4-大法宝2019-必学中间件

Redis 的 4 大法宝,2019 必学中间件 Redis是什么? 全称:REmote DIctionary Server Redis是一种key-value形式的NoSQL内存数据库,由ANSI C编写,遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 Redis最大的特性是它会将所有数据都放在内存中,所以读写速度性能非常好。当然,它也支持将内存中的数据以快照和日志的形式持久化到硬盘,这样即使在断电、机器故障等异常情况发生时数据也不会丢失,Redis能从硬盘中恢复快照数据到内存中。 官网:https://redis.io/ 中文:http://www.redis.cn/ Github:https://github.com/antirez/redis Redis有什么优势? 1、性能高,速度快 Redis命令执行速度非常快,官方给出的读写性能可以达到10W/秒。为什么会如此之快呢?有以下几个因素: 数据存储在内存中,直接与内存连接。由相对底层的C语言实现,离操作系统更近。实现源码很精湛,仅仅几万行代码,简单稳定。使用了单线程模型,无多线程竞争、锁等问题。2、丰富的数据结构 Redis与其他的内存数据库不同的是,Redis拥有丰富的数据类型,如字符串、哈希、列表、集合、有序集合等。正是因为Redis丰富的数据类型,所有它能应用的场景非常多。 3、丰富的特性 除了支持丰富的数据结构外,还支持以下高级功能。 支持键过期功能,可以用来实现定时缓存。支持发布/订阅功能,可以有来实现消息队列。支持事务功能,可以保证多条命令的事务性。支持供管道功能,能够批量处理命令。支持Lua脚本功能。支持集群分片和数据复制功能。支持内存数据持久化硬盘功能。4、丰富的客户端 官网索引:http://www.redis.cn/clients.html 从官网给出的客户端列表可以看出,各种各种的语言都能接入到Redis,接入包括了所有的主流开发语言。 目前使用Redis的公司非常多,国内外都有很多重量级的公司在用。所以,现在学习Redis是大势所趋,学好Redis能为自己在日后的工作谋生中增加一个强有利的竞争手段。 欢迎工作一到五年的Java工程师朋友们加入JavaQQ群:219571750,群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

September 10, 2019 · 1 min · jiezi

不做会死互联网时代的企业必定都要实现中台

AI 前线导读: 自 2018 年底以来,伴随着阿里、腾讯、百度、京东等一众互联网巨头的大规模组织架构调整,“中台”的热度陡然攀升。一时间,各大互联网公司纷纷开始跟随建设中台。中台的概念是被阿里带火的,2015 年,马云正式确定了阿里的中台战略,最早从 2009 年建设“共享事业部”开始,经过十年实践,阿里将自己的技术和业务能力沉淀出了一套综合能力平台,并梳理出了一套中台建设的方法论。如今,阿里提出的“大中台、小前台”的管理模式也已经成为主流的数字化转型思想,很多企业都想学习阿里的中台策略。但长期以来,外界多听闻过关于阿里中台的各种“故事”,但鲜有人知道,阿里的中台到底是什么?究竟在做什么?在 ArchSummit 全球架构师峰会(深圳站)2019现场, InfoQ 有幸采访到了阿里云中间件架构总监谢纯良,听他分享关于阿里巴巴中台建设的实践与思考。 以下为 InfoQ 与阿里云中间件架构总监谢纯良对话全文,有删减。 InfoQ:您是什么时候、是什么契机加入阿里云?目前主要负责哪一块业务? 谢纯良:我此前曾先后在 BEA、Oracle 工作,连续 13 年一直在专注于中间件领域,包括中间件的应用、架构。2015 年,当时只是听说阿里很牛,尤其是做中间件很牛,因为一个偶然的机会就进入了阿里。目前,我在阿里主要负责中间件的应用、商业化等工作。今天再回过头来看,其实这些东西就是外面传说中的业务中台,是其中很重要的组成部分。 InfoQ:在明天的演讲中,您会讲述阿里巴巴数字化转型的实践历程,您觉得有哪些关键的经验可以作为模版,给其他企业借鉴或者直接复制? 谢纯良: 有非常多。 InfoQ:最关键几个点? 谢纯良:外界只听闻过阿里当时为什么要提业务中台这个概念、“大中台”、“小中台”等,但鲜有人知道阿里的业务中台做的究竟是什么,在新闻报道中也找不到特别多相关资料。所以,我们这一次也是正式的、第一次对外去讲一讲,阿里的业务中台究竟是什么。 其实掰开来看,它包括几部分内容:一是阿里这么多年的 IT 建设沉淀的一个技术平台;第二,整个中台建设其实是有很多坑的,阿里在长期的实践中梳理出来了一整套方法论;第三是现在大家看得见的这套业务体系,即在天猫淘宝上交易的这套体系。现在我们要把阿里数字化转型的经验对外输出的话,有一些东西是可以直接拿出去的,比如技术平台,(其他企业)就可以直接复制。 此外,在方法论层面,以往是很少对外讲的,但从今年 5 月开始,我们已经在逐步对外输出一些经验,诸如“怎样建中台“、“怎样管理中台”,“你的业务跑在中台上,怎样不断地进化成长为一个真正意义上的大中台“等等,在建设中台的过程中,“坑”是比较多的,我们积累的一些模版、规范,外部企业是可以直接拿去用的,现在也已经有很多企业在用了,用的效果非常好。 InfoQ:是通过阿里云对外输出吗? 谢纯良:是的,整个阿里巴巴的输出都是通过阿里云。 InfoQ:数字化转型对于企业来说有什么好处? 谢纯良:这是个好问题。今天我们大家都在思考的一个问题是,为什么要做数字化转型?(之前)经过十年、二十年的 IT 建设,很多业务已经实现了数字化、流程自动化了,那为什么还要谈转型?第二个思考的问题是,要转到哪里去?第三个问题是,怎么转? 我曾经跟大量的较大型的外部企业的 CEO、CTO 去聊这几个问题,得到的答案真是五花八门,很多人并没有想清楚为什么要转?有人说因为我现在系统有问题,不好用,听说阿里那个好用。其实,为什么要转?最根本的原因,在我们看来,就是现在的环境变了。我们以前做的系统云有点类似于计划经济,你的终端有多少是定的。而今天在互联网、移动互联网时代,环境、尤其是用户环境已经发生了巨大的变化,你的终端用户已经变成了一个巨大的一个基数,可能是几千万、上亿,像阿里可能都十几亿了。当如此庞大的基数要访问你的系统的时候,这个系统要有抗压的能力,在出现大规模瞬间高峰时,要有抗压能力。 另一方面,今天我们做生意的环境也在变化,从前线下摆个摊别人就会来买,现在很多时候不是这样,现在在流量经济下,要去推荐,那么根据什么去推荐?以前的系统都是孤岛式的建设,信息在一个系统里是非常有限的,如果要做一个精准的推荐,你的数据不是够的,没法去做精准的营销,是做不到千人千面的精准营销的。生意的模式在变化,所以你必须得去转(型),这个“转”是大家有意识的,有痛点,才会转。 转到哪里去?转肯定得有个目标,阿里在 2015 年提出要进入 DT 时代,是跟中台战略配套提出来的。我的理解是,今天数字化转型的目标就是要转到 DT 时代,因为到了 DT 时代,所有数据是有结构化的,数据的清洗也做完了,才能用得上现在大数据的一些技术、AI 的技术,否则就用不上。 那怎么转呢?从旧时代到新时代怎么去转?很多人现在提的是中台,对阿里来说,通过 IT 如何去引领业务的发展这一套体系探索了十年,也形成了一套方法论。业务中台本身是带一套方法论的,如果学习借鉴阿里去“转”,大概率是能成的。因为阿里在十年前就做了数字化转型,那时阿里做的生意就是基于互联网的,比很多传统企业先感知到互联网环境下的这些特殊要求,而他们这几年才逐步感觉到环境变了,所以要转型。 InfoQ:所有的传统企业都需要去做这个(数字化)转型吗? 谢纯良:什么时候需要?如果从信息技术发展的大趋势上看,我觉得是有必要的。我总结过去的 IT 建设时代有点像过去的“马车时代”,随着“汽车时代”的到来,它总要被淘汰掉的。而如今,我们已经迎来了云计算时代,或者说数据时代 /DT 时代,它代表了一种先进的生产力,在这个时代,你才能把现在一些重要的云计算技术、大数据的技术、AI 技术等用起来,不到这个时候你用不起来。因此,我觉得企业都要转,只是早晚的问题。 InfoQ:提到“早晚”,企业需要做怎样的前期准备,或达到一个什么阶段之后,才能开始去做转型? 谢纯良:首先我觉得,如果你的业务还是传统的业务,可能现在转的时机还没到。但如果你的业务跟互联网密切相关,那就要考虑快速去转型。 InfoQ:可否分享一个具体案例 ? 谢纯良:比如我们接触最早的中石化最典型。中石化主要做传统的资源类油品业务,它整个的加油体系都是固定的加油站,好像没必要放到一个中台上去。但它后来又发现,它又做采购又做油品相关、炼油等业务,它需要把上百万与其关系密切的供应商组织起来,这就是一个互联网生意了,这时,它必须有一个互联网时代的玩儿法,或互联网时代的 IT 建设的办法,它才能做。在采用了阿里的中台方法后,中石化转型非常成功。 ...

September 9, 2019 · 1 min · jiezi

Go语言HTTP服务最佳实践译

自从go语言r59版本(一个1.0之前的版本)以来,我一直在写Go程序,并且在过去七年里一直在Go中构建HTTP API和服务. 多年来,我编写服务的方式发生了变化,所以我想分享今天如何编写服务 - 以防模式对您和您的工作有用. 1. Server Struct我的所有组件都有一个server结构,通常看起来像这样: type server struct { db * someDatabase router * someRouter email EmailSender }共享依赖项是结构的字段 2. routes.go我在每个组件中都有一个文件routes.go,其中所有路由都可以存在: package app func(s * server)routes(){ s.router.HandleFunc("/ api/",s.handleAPI()) s.router.HandleFunc("/ about",s.handleAbout()) s.router .HandleFunc("/",s.handleIndex())}这很方便,因为大多数代码维护都是从URL和错误报告开始的,所以只需一眼就routes.go可以指示我们在哪里查看. 3. server 挂载 handler我的HTTPserver 挂载 handler: func(s * server)handleSomething()http.HandlerFunc {...}handler可以通过s服务器变量访问依赖项. 4. return Handler我的处理函数实际上并不处理Request,它们返回一个handler函数. 这给了我们一个闭包环境,我们的处理程序可以在其中运行 func(s * server)handleSomething()http.HandlerFunc { thing:= prepareThing() return func(w http.ResponseWriter,r * http.Request){ // use thing } }该prepareThing只调用一次,所以你可以用它做一次每处理程序初始化,然后用thing在处理程序. 确保只读取共享数据,如果处理程序正在修改任何内容,请记住您需要一个互斥锁或其他东西来保护它. ...

August 28, 2019 · 2 min · jiezi

10-人2-个月-虾mi音乐的监控体系升级之路

背景监控一直是服务端掌握应用运行状态的重要手段,经过近几年的发展,阿里虾米服务端目前已经有 100 多个 Java 应用,承担核心业务的应用也有将近 50 个,对于应用的监控配置也是因人而异。有的人配置的监控比较细,有的应用在经历了多人开发阶段以后,监控就逐渐疏于管理,有些应用的监控项最后修改时间只停留到 2 年以前,早已不适应业务的发展。 与大部分团队一样,虾米也有一个报警处理群,将内部的监控报警平台(如 Sunfire 等)的信息通过机器人投递到群中,由于监控项配置不合理、监控粒度较大,每天报警群都被几十条甚至上百条报警通知狂轰乱炸,长此以往大家对报警已经麻木,大部分报警也不会去处理。 基于这样的现状,虾米 SRE 团队(SRE全称Site Reliability Engineering,最早由Google提出。致力于打造高可用、高拓展的站点稳定性工程)将工作重点放在了对监控的治理上面,经过 2 个月的研发,构建了虾米全新的监控体系。 报警原因分析过去的监控配置可谓五花八门,由应用负责同学配置的一些监控大多局限在应用整体 RT、QPS 的监控和部分业务日志的监控,报警发生时,大部分情况只知道这个应用有了问题,但很难快速定位是哪里出了问题,出了什么问题。一个新接手的同学可能需要经过查看配置项、登录机器、扫描日志甚至去查离线日志等步骤,经过十几分钟才能定位到问题,有的时候甚至需要排查个大半天时间。 经过一段时间的研究和摸索,我们发现一个应用如果在稳定运行了一段时间以后突然发生报警,那么原因通常都是以下几类: 程序 Bug:如代码问题导致空指针、频繁 FullGC 等。上游依赖出问题:上游某个接口出了问题导致本应用出现接口超时、调用失败等。单机故障:某个容器受宿主机应用导致 Load、CPU 突然升高,最终导致超时、线程池满等情况发生。中间件故障:常见的如 Cache、DB抖 动导致一段时间内 RT 增长、超时增多。不过这里需要注意的是,单机 Load 高同样会引发单机读写 Cache、DB 出现问题。监控优化分析了报警原因,下一步就是优化监控。监控的报警可以告诉你出了问题,而好的监控是可以告诉你哪里出了问题。我们以前的监控通常只完成了第一阶段,而不能很好的告诉我们哪里出了问题,要通过一大堆辅助手段去定位。在分析了报警原因以后,我们就要想办法通过监控的手段来精准定位问题。 目前虾米的监控分为故障监控、基础监控和通用监控三类,如下图所示: 故障监控所谓故障监控,就是这些监控发生报警意味着有故障产生了。我们认为一切外在因素如果对应用产生影响,那么必然反应在接口的 RT 和成功率上,要么引起接口 RT 升高,要么导致接口失败数增加,成功率下跌,如果没有这种影响,那么这个外在影响可以被忽略掉。因此我们把接口监控作为故障监控的一大块来重点配置,如果每个应用都配置了核心接口的故障监控,在排查问题时,就很容易定位是否由于上游应用的某个接口导致了我的应用出了问题。 因此我们使用成功率、RT 和错误码三个指标来进行一个接口的故障监控。特别指出的是,对于客户端接口的 RT 监控上,我们没有使用平均 RT,而是使用 Top 75% RT。因为想用它来反应用户侧的感受,比如 RT的 75% 分位线报警阈值设置为 1000ms,那么当这一监控项发生报警时,意味着有 25% 的用户请求接口已经超过 1000ms。通常这一报警阈值设置成用户不能忍受的一个 RT,比如 500ms 或 1000ms。 在故障监控里,我们还设置了应用维度的异常、错误和消息异常三种类型的监控,他们对服务器上的Exception和Error进行监控。这一类监控主要用于快速发现程序bug。例如当一次发布进行时,如果这三种类型的错误增加,那么应该可以考虑进行回滚了。 通用监控大多数情况下,应用出现的问题都是由于单机故障引起的时候,如果某台机器的接口黄金指标突然变化、错误或异常数量突然增多,而其他机器没有什么变化,那就说明是单机引起的。因此我们对应用的故障监控都配置了对应的单机监控,在此处我们还额外引入了 HSF(Dubbo) 线程池满和 HSF(Dubbo) 超时两个类型的单机监控,是因为当单机 Load 高、CPU 有问题时,最为常见的表现就是HSF线程池突然打满,HSF(Dubbo) 超时数量增多,这两个监控同样可以来辅助定位单机问题。通过这一类监控,我们可以方便地接口报警是否由某台机器引起。 ...

August 27, 2019 · 1 min · jiezi

JVMSANDBOX从阿里精准测试走出的开源贡献奖

阿里妹导读:稳定性是历年双11的技术质量保障核心。从 2016 年开始淘宝技术质量部潜心修行,创新地研发了一套实时无侵入的字节码增强框架,于是「JVM-SANDBOX」诞生了,并且顺手在 MTSC 大会上拿了开源贡献奖,今天,我们来瞅瞅这个拿奖的项目。 在近日举行的中国移动互联网测试开发大会(简称MTSC大会),来自淘系技术质量开源项目「JVM-SANDBOX」以及淘系同学参与维护的「 ATX」 包揽了 MTSC 2019 年度开源贡献奖,表彰过去一年在测试领域开源项目中的突出贡献。其中,「JVM-SANDBOX」致力于为服务端稳定性领域提供实时无侵入的字节码增强框架。 一、JVM-Sandbox的诞生功能回归、业务/系统监控、问题排查定位、强弱依赖、故障演练等是阿里 10 年双十一沉淀积累下来的稳定性专项,也是历年双十一质量保障的核心要素。要有效、轻量级地实现这些稳定性专项,都会触及到一块底层技术—— java 字节码增强。如果每个专项都能自己实现一套字节码增强逻辑,实现的门槛高、投入和维护成本高,且不同专项间相互影响造成不可预知的风险。如何屏蔽字节码增强技术的高门槛,降低成本,同时又能支持上层多个专项功能的快速实现和动态管理,成为淘宝技术质量部的目标。从 2016 年开始我们潜心修行,创新地研发了一套实时无侵入的字节码增强框架,于是 「JVM-SANDBOX」 诞生了。 对上面提到的专项进行抽象分析: 故障演练:在运行前,抛出异常或增加运行时间,即:干预方法的执行顺序和改变返回值;强弱依赖梳理:系统运行时,实时记录系统的对外调用情况,即:感知方法的入参和返回值;录制回放:运行时,记录方法的入参和返回值,回放时,不真实对外调用,而是直接返回录制时的返回值。即:感知方法入参和返回值,干预方法执行顺序,改变返回值;精准回归:获取每个请求的行调用链路,根据行调用链路进行场景去重,根据代码改动的情况和行调用链路确定需要回归范围,即:运行时行链路感知。不难发现,要解决这些问题本质就是如何完成 java 方法的环绕管控和运行时行链路的获取,即 AOP 框架的解决方案。目前常用 AOP 框架的解决方案有两种:proxy 和埋点。proxy 的优点在于已实现了统一的 API,减少了重复投入,但是不能实时生效,需要系统编译重启。埋点的优点在于动态生效灵活度高,但是没有统一 API。 要快速解决上边的三个问题,我们需要的 AOP 解决方案必须具备两个特性: 动态可插拔,即实现埋点方式的统一的 API;无侵入性,即解决 JVM 类隔离的问题。基于以上需求,我们研发了 JVM-Sandbox。 二、实现方式JVM-Sandbox 由纯 Java 编码完成,基于 JVMTI 技术规范,为观察和改变代码运行结果提供了即插即用模块接口的容器,提供两个核心功能:实时无侵入 AOP 框架和动态可插拔的模块管理容器。 2.1 JVM-Sandbox的核心功能 使用埋点技术提供统一的 API,来实现无需重启的 AOP 解决方案;使用容器完成 JVM 类隔离,来解决侵入性问题;提供容器管理机制,来完成各种容器的管理。2.2 JVM—Sandbox的核心事件模型 BEFORE、RETURN 和 THROWS 三个环节事件的正常流转和干预流转。 2.3 整体架构 ...

July 5, 2019 · 1 min · jiezi

浅析基于-Serverless-的前后端一体化框架

概述Serverless 是一种“无服务器架构”模式,它无需关心程序运行环境、资源及数量,只需要将精力聚焦到业务逻辑上的技术。基于 Serverless 开发 web 应用,架构师总是试图把传统的解决方案移植到 Serverless 上,虽然可以做到既拥有 Serverless 新技术带来的红利,又能维持住传统开发模式的开发体验。但是,Serverless 技术带来的改变可能不止这些,可能是颠覆整个传统 web 应用开发模式的革命性技术。 开发模式业务应用的开发模式发展是从一体到分裂为前后端,再到前后端融合为一体过程。 注意:后面所说的后端特指后端业务逻辑。 1、早期,一体 没有前后端的概念,那时候的应用都是单机版,所有的业务逻辑都写一起,开发人员不需要关心网络请求,这个时期的工程师完全专注于业务代码的开发。随着业务规模的增长,也暴露了很多问题: 高并发问题高可用问题说明:业务应用升级困难等一些问题,不是本篇文章所关心,所以就不一一列举出来。 2、现在,分裂 前端 + 高可用高并发运维裹挟着的后端业务逻辑: 说明:现在 Serverless 技术已经出现有一段时间了,不但没有解决开发体验的问题,反而带来更多开发体验问题,所以,在这里我并没有突出 Serverless 技术。 解决的问题: 高并发。通过分布式部署和多级负载均衡等技术解决了业务的高并发问题高可用。通过主从架构等技术解决了业务的高可用问题解决一个问题,带来一堆问题: 分裂业务应用。为了解决高可用和高并发,业务应用引入了分布式架构,通过负载均衡和主从模式来保证高可用和高并发问题,但是这种解决方案对业务应用是侵入式的,从而导致原本高内聚一体化的应用分裂成前端和后端污染业务代码。与高可用、高并发和运维相关的逻辑与后端业务逻辑交织在一起,让后端技术门槛变高,导致需要多个后端工程师才能掌握所有后端技术增加联调成本。前后端的联调工作做日益繁重,成了工程开发效率提升的瓶颈。新功能和 BUG 需要前后端工程师配合才能完成,你如果是全栈开发工程师,你肯定深有体会,很多 BUG 一看就知道是前端问题,还是后端问题不匹配的前后端技术发展速度,前端技术发展迅猛,后端技术相对稳定,前端只能被动的去适配后端,让前端最新的技术在使用体验上大打折扣。最理想的方式是前后端通盘考量,整体发展,不要出现本来后端只需要优化一行代码的事,让前端写一百行代码来实现限制了代码抽象。因为实现的是同一个业务需求,所以前后端代码有高度的相关性,如果我们能在前后端代码之上抽象代码逻辑,肯定能有很大的作为。同时,代码的开发和维护也有质的提升,前后端分裂导致我们不得不局限在前端或者后端进行代码的抽象,抽象出来的代码可能是片面而重复的增加技术复杂度。前后端分裂,前后端工程师各自为营,形成各自的技术栈,包括语言、工具和理念,导致单个工程师维护整个业务应用变得极度困难,也让前后端工程师排斥彼此的技术栈,随着时间的推移,技术栈差异越来越大,一个项目,不管多小,至少两位工程师以上,全栈开发工程师另当别论增加运维成本。需要专门的运维工程师来运维,虽然,现在通过技术手段降低了运维的成本,但是目前运维成本依然很高,难度依然很大这也是为什么创业小公司喜欢全栈开发工程师,因为在创业早期,高可用和高并发的需求不是那么迫切,因而运维也相对简单,使用全栈开发工程师,不仅缩短了项目交付周期,而且也降低了公司的运营成本,这对创业小公司是至关重要的。 3、未来,融合回到到一体 前端 + 后端 + Serverless + 平台服务   =>  业务应用 + Serverless + 平台服务: 说明:共享逻辑是前后端的共享逻辑,在过去,由于前后端分裂,是很难做到前后端层面的代码抽象的,前后端融合后,让这件事变得简单自然。 带来困惑: 前后端分工合作,不是很好吗?在过去,将一个复杂的问题分解成多个简单的子问题,高并发和高可用没法做到不侵入业务应用,这种确实是一种很好的解法,也是没办法中的办法。前后端分工合作带来的成本问题,越发凸显。现在 Serverless 透明的解决了高并发和高可用问题,那么我们为什么还需要从技术维度来划分,我们不是更加推荐按业务维度来划分吗?后端依然很难,驾驭前后端的门槛依然很高?后端代码逻辑虽然没有了高并发和高可用的裹挟,还是会很难,比如 AI。我相信类似这种很难的业务,现在可能有,未来一定会有相关的开发工具包或者平台服务为我们解决,让这些很难的技术平民化。难的技术交给专业的人解决。找回初心: 回归业务,前后端一体化。随着 Serverless 技术的出现,解决了高可用、高并发和运维问题,作为工程师的我们是不是应该回头看看,找回初心:专注于业务代码。让原本在一起的后端业务代码与前端代码再次融合。因此,前后端一体化难道不是我们失去已久的应用开发终极解决方案吗?现状Serverless 已经做到了以下两点: 工程师只需要关心业务逻辑上的技术拥有接近于传统应用开发体验(解决历史遗留问题,可能还有些距离)传统应用框架,食之无味,弃之可惜: 目前,很多用户已经感知到了 Serverless 带来的高可用、高并发和免运维的好处,用户能够很自然的想到如果能将现有的开发框架移植到 Serverless 上,那就太好不过了。Serverless 平台很自然会提供现有框架的移植方案。解决的问题是将传统的解决方案移植到 Serverless 上,让用户在 Serverless 上拥有传统的开发体验应用框架找回初心: ...

July 2, 2019 · 1 min · jiezi

WhatTomcat竟然也算中间件

关于 MyCat 的铺垫文章已经写了两篇了: MySQL 只能做小项目?松哥要说几句公道话!北冥有 Data,其名为鲲,鲲之大,一个 MySQL 放不下!今天是最后一次铺垫,后面就可以迎接大 Boss 了! <!--more--> 本来今天就该讲 MyCat 了,但是我发现还有一个概念值得和大家聊一下,那就是 Java 中间件! 因为 MyCat 是一个分布式数据库中间件,要理解 MyCat ,那你就得先知道到底什么是中间件! 松哥去年在一次外训中专门讲过中间件,本来想直接和大家分享一下讲稿,但是没找到,所以又动手敲了下。 中间件简介说起中间件,很多人首先想到的就是消息中间件,那么除了消息中间件呢?其实我们日常开发中,接触到的中间件太多了,我们来看维基百科上的一段介绍: 中间件(英语:Middleware),又译中间件、中介层,是提供系统软件和应用软件之间连接的软件,以便于软件各部件之间的沟通。在现代信息技术应用框架如 Web 服务、面向服务的体系结构等项目中应用比较广泛。如数据库、Apache 的 Tomcat ,IBM 公司的 WebSphere ,BEA 公司的 WebLogic 应用服务器,东方通公司的 Tong 系列中间件,以及 Kingdee 公司的等都属于中间件。看到这个,你可能会大吃一惊,原来我们不知不觉不知不觉中已经用过这么多中间件了!甚至连 Tomcat 也是一个中间件! 中间件,顾名思义,就是连接在两个软件之间的东西,是软件之间的一个粘合剂,一个胶水一样的东西。它位于操作系统和我们的应用程序之间,可以让开发者方便地处理通信、输入和输出,使开发者能够专注于自己的业务逻辑开发。 这么一说,好像 Tomcat 确实还有点像中间件!位于我们的操作系统和应用程序之间! 中间件分类中间件有很多,早在 1998 年 IDC 公司就将中间件分成了 6 大类,国内 2005 年之前出版的中间件相关的书上,很多都是按照这 6 大类来分的,分别是: 终端仿真/屏幕转换数据访问中间件(UDA)远程过程调用中间件(RPC)消息中间件(MOM)交易中间件(TPM)对象中间件这里边除了消息中间件和交易中间件大家可能听说过之外,其他的中间件估计都很少听说,这是因为时代在变化,有的中间件慢慢被淘汰了(例如 终端仿真/屏幕转换 中间件),有的则慢慢合并到其他框架中去了(例如 远程过程调用中间件)。 数据库中间件那么什么是数据库中间件呢? 前面文章我们提到,如果数据量比较大的话,我们需要对数据进行分库分表,分完之后,原本存在一个数据库中的数据,现在就存在多个数据库中了,那么我们的项目结构可能就是下面这个样子了: 我们要在 Java 代码中配置复杂的多数据源,配置读写分离,数据查询的时候还要进行数据的预处理,例如从多个 DB 上加载到的数据要先进行排序、过滤等等操作,这样我们的 Java 代码就参杂了很多业务无关的方法,而且这些参杂进来的代码,大多数都还是重复的。 ...

June 29, 2019 · 1 min · jiezi

蚂蚁金服-Service-Mesh-落地实践与挑战-GIAC-实录

本文整理自 GIAC(GLOBAL INTERNET ARCHITECTURE CONFERENCE)全球互联网架构大会,蚂蚁金服平台数据技术事业群技术专家石建伟(花名:卓与)的分享。分享基于 Service Mesh 的理念,结合蚂蚁金服内部实际场景,将中间件、数据层、安全层等能力从应用中剥离出来后下沉至独立的 Sidecar SOFAMosn 中,结合 Kubernetes 运维体系,提供应用无感知的情况下升级基础设施层能力的案例。 本次分享将从以如下次序展开进行: 蚂蚁金服当前的服务化现状在看蚂蚁金服的服务化架构之前我们先从一个简单的服务化调用示例说起,下图是 SOFARPC 基本原理: 图1. SOFARPC 基本原理 我们从上图可以看出,构建一个服务化框架需要有服务注册中心,有服务定义,调用方和服务提供方使用相同的服务定义来互相通讯。通过服务注册中心,调用方可以直接订阅到服务提供方的地址,采用点对点的方式直接发起请求。客户端内可实现服务发现、路由寻址、负载均衡、限流熔断等能力来增强服务通讯能力。通过我们开源的 SOFARPC、SOFARegistry、SOFABoot,用户已经可以直接构建起微服务体系,助力业务发展。 蚂蚁金服发展至今,双 11 系统需要应对的交易洪峰逐年递增: 图2. 历年双 11 交易额与峰值数据 每秒 26.5 万笔交易是 2017 年双 11 的峰值数据,这个数据背后有非常复杂的架构支持,LDC 单元化架构是蚂蚁金服沉淀多年的核心架构,依靠这个架构实现每年峰值交易量飞速增长下系统依然能平滑渡过。我们来简要看下 LDC 架构: 图3. LDC 架构示例 上图摘自 金融级分布式架构 中的 素描单元化 一文,这里不详细展开。LDC 的单元化架构给应用的服务化带来更多的规范与抽象,服务路由中需要考虑单元间的调用,跨机房调用等更多场景。这里主要希望表达的是 LDC 架构给 RPC 调用带来更高的复杂度。 服务化痛点中间件版本升级在上面介绍背景时,有介绍到目前 LDC 架构下服务调用的复杂度,这些复杂度目前是直接体现在应用的代码中。对于业务同学来讲,一个应用的关注重点是如何实现业务逻辑,至于高可用、容灾等能力更多是整体架构层面会考虑的点。应用内通过引入 RPC 的 jar 包即可获得 LDC 架构下服务调用各种能力的支撑,带来便利的同时也可以看到这种模式的缺点: 图4. APP 业务与 SDK 组成部分应用内除业务逻辑之外,由中间件的 SDK 引入大量外部依赖,来完成服务发现、路由寻址、负载均衡、限流熔断、序列化、通讯等能力,每个组件的引入都可能带来稳定性风险,以及更高的升级成本。 ...

June 28, 2019 · 3 min · jiezi

同学要不要来挑战双11零点流量洪峰

阿里妹导读:双十一的零点,整个电商系统的请求速率到达峰值。如果将这些请求流量只分配给少部分 server,这些机器接收到的请求速率会远超过处理速率,新来的任务来不及处理,就会产生请求任务堆积。今年的中间件性能挑战赛就围绕“挑战双11零点流量洪峰”展开。自2015年开始,中间件性能挑战赛已经成功举办了四届,被历年大赛选手称为“中间件技术的风向标”。接下来,跟随阿里巴巴中间件团队的郭浩,一起来围观赛题,解读赛题。 在现代分布式应用中,服务请求是由物理机或虚拟机组成的 server 池进行处理的。 通常,server 池规模巨大且服务容量各不相同,受网络、内存、CPU、下游服务等各种因素影响,一个 server 的服务容量始终处于动态变动和趋于稳定的状态,如何设计和实现这种系统的负载均衡算法是一个极具挑战的难题。 自适应负载均衡的需求背景负载均衡有两个主要目标: 保持较短的请求响应时间和较小的请求阻塞概率;负载均衡算法的 overhead 在可控级别,不占用过多的 CPU 、网络等资源。自适应负载均衡是指无论系统处于空闲、稳定还是繁忙状态,负载均衡算法都会自动评估系统的服务能力,进行合理的流量分配,使整个系统始终保持较好的性能,不产生饥饿或者过载、宕机。 这种算法对于现在的电商系统、数据中心、云计算等领域都很有必要,使用自适应负载均衡能够更合理的利用资源,提高性能。 对用户而言,一旦产生任务堆积,请求会变慢甚至超时,体验严重下降,甚至导致服务不可用。而处理请求的机器也会由于堆积的任务越来越多而发生严重过载,直到被打垮。剩余的尚未宕机的其它机器会逐渐重复这个过程,直至整个应用不可用,发生系统故障。 为了避免这种情况发生,我们可能会想到一种常用的办法:在服务上线前提前进行压测,使用压测的容量作为限流值,当线上服务的请求速率大于限流值的时候,服务拒绝新到的服务,从而保障服务始终可用。但是这种方式也存在问题:压测时测试的容量进行限流通常会趋于保守,不能充分发挥异构系统的全部性能;也无法智能地应对由于网络、下游服务变化而导致的容量下降等问题,系统仍然存在宕机风险。 因此,我们需要具备自适应能力的负载均衡算法,来更好地进行流量分配调度以及稳定性保障,追求极致性能,挑战大促等场景下的流量洪峰。 结合中间件性能挑战赛的赛题 我们结合「第五届中间件性能挑战赛」中的初赛场景,来一起探讨一下设计和实现一个自适应的负载均衡的基本思路。 本次挑战赛的场景由施压程序(阿里云性能测试PTS)、服务调用方(Consumer)和三个规格不同的服务提供方(Provider) 组成。在评测过程中,每个程序都部署在不同的物理机上,以避免因 CPU、网络资源的竞争,导致评测程序抖动,影响最终评测成绩。 Becnhmarker 负责请求 Consumer, Consumer 收到请求后,从三台物理规格不同、服务响应时间和最大并发都不同的 Provider 中选择一个进行调用并返回结果。选择哪一个 Provider 进行调用的流程就是本次挑战赛需要实现的负载均衡算法。 为了简化环境部署和提升性能,本次挑战赛没有使用服务注册和发现机制。三个 Provider 对应的 URL 都已经被直接配置在了 Consumer 中,选手在开发和测试时可直接通过 Provider-small 等 hostname 访问相应的 Provider。 赛题分析题目描述很简单,不考虑 Consumer 直接拒绝的情况下,场景可以简化为 3 选 1 的问题,但如何进行这个决策则是本次挑战赛考察的难点和重点。 官方题目组提供了 Random 算法作为默认实现:从 3 个 Provider 中随机取任意一个。对于单 dispatcher (在本次赛题中是 Consumer) 同构系统的场景,Random可以达到渐近负载均衡, 每个 Provider 接收到的总请求数接近。但是对于多 dispatcher 或异构系统而言,Random 算法由于缺少全局状态,无法保证全局随机,极端条件下,多个 dispatcher 可能将请求同时分配到一台 Provider 上,导致系统存在服务过载和宕机的风险;异构系统中,不同 Provider 服务容量实际是不同的,即使每个 Provider 请求速率相同也会产生空闲、稳定、过载等不同的服务状态,无法实现最优流量分配,更不能做到响应时间最小。显而易见,Random 并不是符合赛题要求的自适应算法。 ...

June 21, 2019 · 1 min · jiezi

蚂蚁金服轻量级监控分析系统-SOFALookout-服务端开源

SOFAStack Scalable Open Financial  Architecture Stack 是蚂蚁金服自主研发的金融级分布式架构,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。SOFALookout 是蚂蚁金服在 SOFAStack 体系内研发开源的一款解决系统的度量和监控问题的轻量级中间件服务。本文给大家介绍下 SOFALookout 服务器端主要提供的特性以及使用方式。SOFALookout:https://github.com/sofastack/sofa-lookout 前言容器,K8S,微服务,Mesh 以及 Serverless 这些新技术方向正在根本的变革我们运行软件的方式。我们构建的系统更加分布式化,另外由于容器,系统的生命周期更加短,变得易逝。针对这些变化,SOFALookout 希望提供一套轻量级解决方案。之前 SOFALookout 已经开源客户端的能力。今天,SOFALookout 服务器端 Metrics 部分的代码终于正式开源啦!本文给大家介绍下 SOFALookout 服务器端的主要特性以及使用方法。 什么是 SOFALookoutSOFALookout 是蚂蚁金服开源的一款解决系统的度量和监控问题的轻量级中间件服务。它提供的服务包括:Metrics 的埋点、收集、加工、存储与查询等。该开源项目包括了两个独立部分,分别是客户端与服务器端服务。 SOFALookout 目标是打造一套轻量级 Observability 实时工具平台,帮助用户解决基础设施、应用和服务等的监控和分析的问题。SOFALookout(目前已开源部分) 是一个利用多维度的 metrics 对目标系统进行度量和监控的项目。SOFALookout 的多维度 metrics 参考 Metrics2.0 标准。 SOFALookout :https://github.com/sofastack/sofa-lookoutSOFALookout 安装文档:https://www.sofastack.tech/sofa-lookout/docs/quickstart-metrics-server  SOFALookout 服务器端的主要特性: 适配社区主要 Metrics 数据源协议写入(比如: Prometheus,Metricbeat 等);数据的存储支持扩展,暂时开源版默认支持 Elasticsearch, 并且透明和自动化了相关运维操作;遵循 Prometheus 查询 API 的标准以及支持 PromQL,并进行了适当改进;自带数据查询的控制台,并支持 Grafana 进行数据可视化;使用简单,支持单一进程运行整个服务器端模块。随着 SOFALookout (metrics)服务器端代码开源,metrics 数据的处理已经形成闭环。后续我们将会进一步开源 Trace 和 Event 相关的服务能力,敬请期待。 SOFALookout 项目结构服务器端代码分别包括两部分:Gateway 模块和 Server 模块。如下图所示(展示了 SOFALookout 源码项目的模块概要结构) ├── boot├── client├── gateway└── server项目中的 boot 模块作用是方便集成和运行服务端的模块,既可以单独运行 Gateway 和 Server 的服务,也可以借助 SOFAArk 完成(Gateway 和 Server)的 All in One 的合并为单一进程运行。 ...

June 20, 2019 · 1 min · jiezi

Redis使用进阶

Redis之使用教程(Java版)博客地址 https://blog.piaoruiqing.com/blog/2019/06/11/redis使用进阶 关键词Jedis: redis java客户端实现.Lettuce: redis java客户端实现, 基于netty.spring-data-redis: Spring针对redis的封装, 配置简单, 提供了与Redis存储交互的抽象封装, 十分优雅, 也极具扩展性. 可集成Jedis、Lettuce等redis客户端. springboot2.0后官方默认集成的客户端从Jedis改为Lettuce.前言本文将针对使用Java集成Redis进行讲解, Jedis及Lettuce的使用仅作简单描述, spring的redis集成及使用将作为主要讲解内容. Jedishttps://github.com/xetorthio/jedis引入依赖: <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.3</version></dependency>Jedis是对redis命令的封装, 使用上基本与redis-cli无异, 操作string的使用示例如下: /** jedis pool */private static final JedisPool POOL = new JedisPool(new JedisPoolConfig(), "test-redis-server", 6379);// test Binary-safe strings with Jedistry (Jedis jedis = POOL.getResource()){ { // SET mykey myvalue String result = jedis.set("mykey", "myvalue"); LOGGER.info("cmd: SET mykey myvalue, result: {}", result); } { // GET mykey String result = jedis.get("mykey"); LOGGER.info("cmd: GET mykey, result: {}", result); } { // KEYS my* Set<String> keys = jedis.keys("my*"); LOGGER.info("cmd: KEYS my*, result: {}", JsonUtils.writeValueAsString(keys, true)); } { // EXISTS mykey Boolean result = jedis.exists("mykey"); LOGGER.info("cmd: EXISTS mykey, result: {}", result); } { // DEL mykey Long result = jedis.del("mykey"); LOGGER.info("cmd: DEL mykey, result: {}", result); } { // GET mykey String result = jedis.get("mykey"); LOGGER.info("cmd: GET mykey, result: {}", result); }}JedisPool: Jedis并不是线程安全的, 所以多线程情况下不应共用Jedis实例, 但创建大量的Jedis会造成不必要的开销甚至对性能产生较大影响, 故使用JedisPool来避免这些问题, 它是一个线程安全的网络连接池. 可以使用它可靠地创建多个Jedis实例, 完成后将Jedis实例回收到连接池中.JedisPool.getResource: 从连接池获取一个Jedis连接, 注意: Jedis使用完毕后需要调用Jedis.close方法释放资源.(Jedis实现了AutoCloseable, 推荐使用try-with-resource的写法)Lettucehttps://lettuce.io/引入依赖: ...

June 12, 2019 · 4 min · jiezi

不改代码也能全面-Serverless-化阿里中间件如何破解这一难题

阿里妹导读:Serverless 话题涉及范围极广,几乎包含了代码管理、测试、发布、运维和扩容等与应用生命周期关联的所有环节。在线应用如何不改代码也能迁移到 Serverless 架构?今天,我们来揭秘阿里巴巴成千上万在线应用的Serverless 演进过程。AWS Lambda 是 Serverless 领域的标志性产品,但如果将其应用于核心业务,可能会遇到以下难题:(仅代表作者个人观点) 要求用户以 Function 为单位进行开发,全新的开发框架,云厂商强绑定,社区主流技术栈迁移成本高;Function 启动速度要足够快,毫秒级或者秒级,这个限制对适用场景有很强的约束;Function 之间的调用通过 API Gateway,响应时间更长。Cloud Service Engine 云服务引擎(以下简称CSE),是阿里云中间件团队开发的面向通用 Serverless 计算的中间件产品,目的是具备 AWS Lambda 的各种优势,同时可以解决用户在使用 AWS Lambda 时遇到的难题。 什么是 Serverless?AWS 对 Serverless 定义是:(摘自 AWS 官网) AWS 无服务器平台提供的功能:(摘自 AWS 官网) AWS 的整套 Serverless 方案非常完善,但是没有解决存量应用如何迁移到 Serverless 架构的问题。仅仅是针对新开发的应用,建议用户使用 FaaS 方式开发,才有机会转向 Serverless 架构。笔者认为,要将 Serverless 架构大规模推广,必须要能有针对存量业务的解决方案。 Serverless 对云计算的价值云计算,归根结底是一种 IT 服务提供模式,不论是公共云还是专有云(以 IT 设备的归属不同分类),其本质都是帮助 IT 的最终使用者随时随地,并且简便快速地,获取 IT 服务,目前,IaaS、PaaS 都已经做到了按需付费,PaaS 甚至做到了按请求付费,如 DB,CACHE,MQ 等,但是 IaaS 的付费粒度仍然是时间维度,最快按照小时付费,以分钟来交付。 ...

June 4, 2019 · 2 min · jiezi

Nacos-Namespace-和-Endpoint-在生产环境下的最佳实践

随着使用 Nacos 的企业越来越多,遇到的最频繁的两个问题就是:如何在我的生产环境正确的来使用 namespace 以及 endpoint。这篇文章主要就是针对这两个问题来聊聊使用 nacos 过程中关于这两个参数配置的最佳实践方式。 namespce关于 namespace ,以下主要从 namespace 的设计背景 和 namespace 的最佳实践 两个方面来讨论。 namespace 的设计背景namespace 的设计是 nacos 基于此做多环境以及多租户数据(配置和服务)隔离的。即: 从一个租户(用户)的角度来看,如果有多套不同的环境,那么这个时候可以根据指定的环境来创建不同的 namespce,以此来实现多环境的隔离。例如,你可能有日常,预发和生产三个不同的环境,那么使用一套 nacos 集群可以分别建以下三个不同的 namespace。如下图所示: 从多个租户(用户)的角度来看,每个租户(用户)可能会有自己的 namespace,每个租户(用户)的配置数据以及注册的服务数据都会归属到自己的 namespace 下,以此来实现多租户间的数据隔离。例如超级管理员分配了三个租户,分别为张三、李四和王五。分配好了之后,各租户用自己的账户名和密码登录后,创建自己的命名空间。如下图所示。 注意: 该功能还在规划中。 namespace 的最佳实践关于 namespace 的最佳实践 ,这部分主要包含有两个 Action: 如何来获取 namespace 的值namespace 参数初始化方式如何来获取 namespace 的值无论您是基于 Spring Cloud 或者 Dubbo 来使用 nacos,都会涉及到 namespace 的参数输入,那么这个时候 namespace 的值从哪里可以获取呢? 如果您在使用过程中没有感知到这个参数的输入,那么 nacos 统一会使用一个默认的 namespace 作为输入,nacos naming 会使用 public 作为默认的参数来初始化,nacos config 会使用一个空字符串作为默认的参数来初始化。。如果您需要自定义自己的 namespace,那么这个值该怎么来产生?可以在 nacos 的控制台左边功能侧看到有一个 命名空间 的功能,点击就可以看到 新建命名空间 的按钮,那么这个时候就可以创建自己的命名空间了。创建成功之后,会生成一个命名空间ID,主要是用来避免命名空间名称有可能会出现重名的情况。因此当您在应用中需要配置指定的 namespace 时,填入的是命名空间ID。重要的事情说三遍, 当您在应用中需要配置指定的 namespace 时,填入的是命名空间 ID当您在应用中需要配置指定的 namespace 时,填入的是命名空间 ID当您在应用中需要配置指定的 namespace 时,填入的是命名空间 ID说明: namesace 为 public 是 nacos 的一个保留控件,如果您需要创建自己的 namespace,最好不要和 public 重名,以一个实际业务场景有具体语义的名字来命名,以免带来字面上不容易区分自己是哪一个 namespace。 ...

May 28, 2019 · 1 min · jiezi

RabbitMQ高级特性消费端限流策略实现

应用范围为服务访问量突然剧增,原因可能有多种外部的调用或内部的一些问题导致消息积压,对服务的访问超过服务所能处理的最大峰值,导致系统超时负载从而崩溃。业务场景举一些我们平常生活中的消费场景,例如:火车票、机票、门票等,通常来说这些服务在下单之后,后续的出票结果都是异步通知的,如果服务本身只支持每秒1000访问量,由于外部服务的原因突然访问量增加到每秒2000并发,这个时候服务接收者因为流量的剧增,超过了自己系统本身所能处理的最大峰值,如果没有对消息做限流措施,系统在这段时间内就会造成不可用,在生产环境这是一个很严重的问题,实际应用场景不止于这些,本文通过RabbitMQ来讲解如果对消费端做限流措施。 消费端限流机制RabbitMQ提供了服务质量保证 (QOS) 功能,对channel(通道)预先设置一定的消息数目,每次发送的消息条数都是基于预先设置的数目,如果消费端一旦有未确认的消息,这时服务端将不会再发送新的消费消息,直到消费端将消息进行完全确认,注意:此时消费端不能设置自动签收,否则会无效。 在 RabbitMQ v3.3.0 之后,放宽了限制,除了对channel设置之外,还可以对每个消费者进行设置。 以下为 Node.js 开发语言 amqplib 库对于限流实现提供的接口方法 prefetch export interface Channel extends events.EventEmitter { prefetch(count: number, global?: boolean): Promise<Replies.Empty>; ...}prefetch 参数说明: number:每次推送给消费端 N 条消息数目,如果这 N 条消息没有被ack,生产端将不会再次推送直到这 N 条消息被消费。global:在哪个级别上做限制,ture 为 channel 上做限制,false 为消费端上做限制,默认为 false。建立生产端生产端没什么变化,和正常声明一样,关于源码参见rabbitmq-prefetch(Node.js客户端版Demo) const amqp = require('amqplib');async function producer() { // 1. 创建链接对象 const connection = await amqp.connect('amqp://localhost:5672'); // 2. 获取通道 const channel = await connection.createChannel(); // 3. 声明参数 const exchangeName = 'qosEx'; const routingKey = 'qos.test001'; const msg = 'Producer:'; // 4. 声明交换机 await channel.assertExchange(exchangeName, 'topic', { durable: true }); for (let i=0; i<5; i++) { // 5. 发送消息 await channel.publish(exchangeName, routingKey, Buffer.from(`${msg} 第${i}条消息`)); } await channel.close();}producer();建立消费端const amqp = require('amqplib');async function consumer() { // 1. 创建链接对象 const connection = await amqp.connect('amqp://localhost:5672'); // 2. 获取通道 const channel = await connection.createChannel(); // 3. 声明参数 const exchangeName = 'qosEx'; const queueName = 'qosQueue'; const routingKey = 'qos.#'; // 4. 声明交换机、对列进行绑定 await channel.assertExchange(exchangeName, 'topic', { durable: true }); await channel.assertQueue(queueName); await channel.bindQueue(queueName, exchangeName, routingKey); // 5. 限流参数设置 await channel.prefetch(1, false); // 6. 限流,noAck参数必须设置为false await channel.consume(queueName, msg => { console.log('Consumer:', msg.content.toString()); // channel.ack(msg); }, { noAck: false });}consumer();未确认消息情况测试在 consumer 中我们暂且将 channel.ack(msg) 注释掉,分别启动生产者和消费者,看看是什么情况? ...

May 23, 2019 · 2 min · jiezi

Redis闲谈1构建知识图谱

场景:Redis面试 (图片来源于网络) 面试官: 我看到你的简历上说你熟练使用Redis,那么你讲一下Redis是干嘛用的?小明: (心中窃喜,Redis不就是缓存吗?)Redis主要用作缓存,通过内存高效地存储非持久化数据。 面试官: Redis可以用作持久化的存储吗? 小明 :嗯...应该可以吧... 面试官: 那Redis怎么进行持久化操作呢? 小明:嗯...不是太清楚。 面试官: Redis的内存淘汰机制有哪些? 小明:嗯...没了解过 面试官:我们还可以用Redis做哪些事情?分别利用了Redis的哪个指令? 小明:我只知道Redis还可以做分布式锁、消息队列... 面试官:好了,我们进入下一个话题... 思考:很明显,小明同学在面试过程中关于Redis的表现和回答肯定是比较失败的。Redis是我们工作中每天都会使用到的东西,为什么一到面试却变成了丢分项呢? 作为开发者,我们习惯了使用大神们已经封装好的东西,以此保障我们能够更专注于业务开发,却不知道这些常用工具的底层实现是什么,因此尽管平时应用起来得心应手,但一到面试还是无法让面试官眼前一亮。 本文总结了一些Redis的知识点,有原理有应用,希望可以帮助到大家。 一、Redis是什么REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。Redis是一个开源的使用ANSI 、C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。 这里我引用了Redis教程里对Redis的描述,很官方,但是很标准。 **可基于内存亦可持久化的日志型、Key-Value数据库。**我认为这个描述很贴切很全面。 1.1 Redis的行业地位Redis是互联网技术领域使用最为广泛的存储中间件,因超高的性能、完美的文档、多方面的应用能力以及丰富完善的客户端支持在存储方面独当一面,广受好评,尤其以其性能和读取速度而成为了领域中最受青睐的中间件。基本上每一个软件公司都会使用Redis,其中包括很多大型互联网公司,比如京东、阿里、腾讯、github等。因此,Redis也成为了后端开发人员必不可少的技能。 1.2 知识图谱在我看来,学习每一项技术,都需要有一个清晰的脉络和结构,不然你也不知道自己会了哪些、还有多少没学会。就像一本书,如果没有目录章节,也就失去了灵魂。 因此我试图总结出Redis的知识图谱,也称为脑图,如下图所示,可能知识点不是很全,后续会不断更新补充。 本系列文章的知识点也会和这个脑图基本一致,本文先介绍Redis的基本知识,后续文章会详细介绍Redis的数据结构、应用、持久化等多个方面。 二、Redis优点2.1 速度快作为缓存工具,Redis最广为人知的特点就是快,到底有多快呢?Redis单机qps(每秒的并发)可以达到110000次/s,写的速度是81000次/s。那么,Redis为什么这么快呢? 绝大部分请求是纯粹的内存操作,非常快速;使用了很多查找操作都特别快的数据结构进行数据存储,Redis中的数据结构是专门设计的。如HashMap,查找、插入的时间复杂度都是O(1);采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗CPU,不用去考虑各种锁的问题,不存在加锁、释放锁操作,没有因为可能出现死锁而导致的性能消耗;用到了非阻塞I/O多路复用机制。2.2 丰富的数据类型Redis有5种常用的数据类型:String、List、Hash、set、zset,每种数据类型都有自己的用处。 2.3 原子性,支持事务Redis支持事务,并且它的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。 2.4 丰富的特性Redis具有丰富的特性,比如可以用作分布式锁;可以持久化数据;可以用作消息队列、排行榜、计数器;还支持publish/subscribe、通知、key过期等等。当我们要用中间件来解决实际问题的时候,Redis总能发挥出自己的用处。 三、Redis和Memcache对比Memcache和Redis都是优秀的、高性能的内存数据库,一般我们说到Redis的时候,都会拿Memcache来和Redis做对比。(为什么要做对比呢?当然是要衬托出Redis有多好,没有对比,就没有伤害~)对比的方面包括: 3.1 存储方式Memcache把数据全部存在内存之中,断电后会挂掉,无法做到数据的持久化,且数据不能超过内存大小。Redis有一部分数据存在硬盘上,可以做到数据的持久性。3.2 数据支持类型Memcache对数据类型支持相对简单,只支持String类型的数据结构。Redis有丰富的数据类型,包括:String、List、Hash、Set、Zset。3.3 使用的底层模型它们之间底层实现方式以及与客户端之间通信的应用协议不一样。Redis直接自己构建了VM机制 ,因为一般的系统调用系统函数,会浪费一定的时间去移动和请求。3.4 存储值大小Redis最大可以存储1GB,而memcache只有1MB。看到这里,会不会觉得Redis特别好,全是优点,完美无缺?其实Redis还是有很多缺点的,这些缺点平常我们该如何克服呢? 四、Redis存在的问题及解决方案4.1 缓存数据库的双写一致性的问题问题:一致性的问题是分布式系统中很常见的问题。一致性一般分为两种:强一致性和最终一致性,当我们要满足强一致性的时候,Redis也无法做到完美无瑕,因为数据库和缓存双写,肯定会出现不一致的情况,Redis只能保证最终一致性。 解决:我们如何保证最终一致性呢? 第一种方式是给缓存设置一定的过期时间,在缓存过期之后会自动查询数据库,保证数据库和缓存的一致性。如果不设置过期时间的话,我们首先要选取正确的更新策略:先更新数据库再删除缓存。但我们删除缓存的时候也可能出现某些问题,所以需要将要删除的缓存的key放到消息队列中去,不断重试,直到删除成功为止。4.2 缓存雪崩问题问题: 我们应该都在电影里看到过雪崩,开始很平静,然后一瞬间就开始崩塌,具有很强的毁灭性。这里也是一样的,我们执行代码的时候将很多缓存的实效时间设定成一样,接着这些缓存在同一时间都会实效,然后都会重新访问数据库更新数据,这样会导致数据库连接数过多、压力过大而崩溃。 解决: 设置缓存过期时间的时候加一个随机值。设置双缓存,缓存1设置缓存时间,缓存2不设置,1过期后直接返回缓存2,并且启动一个进程去更新缓存1和2。4.3 缓存穿透问题问题: 缓存穿透是指一些非正常用户(黑客)故意去请求缓存中不存在的数据,导致所有的请求都集中到到数据库上,从而导致数据库连接异常。 解决: 利用互斥锁。缓存失效的时候,不能直接访问数据库,而是要先获取到锁,才能去请求数据库。没得到锁,则休眠一段时间后重试。采用异步更新策略。无论key是否取到值,都直接返回。value值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。提供一个能迅速判断请求是否有效的拦截机制。比如利用布隆过滤器,内部维护一系列合法有效的key,迅速判断出请求所携带的Key是否合法有效。如果不合法,则直接返回。4.4 缓存的并发竞争问题问题: 缓存并发竞争的问题,主要发生在多线程对某个key进行set的时候,这时会出现数据不一致的情况。 ...

May 5, 2019 · 1 min · jiezi

蚂蚁金服SOFA开源负责人鲁直不只是中间件未来会开源更多

摘要: 蚂蚁金服开源也不只是 SOFA 中间件框架,未来会开源更多的东西,包括 AI 方面的一些技术,也希望整个社区能够多关注蚂蚁金服在开源上面未来的举措。本文转载自微信公众号:Linux中国,原作者:王兴宇 近日,技术媒体Linux中国的创始人王兴宇对蚂蚁金服SOFA开源负责人鲁直,就SOFA 5、ServiceMesh、Serverless、Seata等技术内容进行了探讨,以下为专访文章。 虽然我和鲁直在微信上已经联系很久了,但这还是第一次见面。交谈中,我了解到鲁直是2009 年加入阿里巴巴工作,已经有十年了。刚开始是在1688.COM 做业务系统,对中间件技术非常感兴趣,也会经常研究各种中间件的实现和功能。后来在 2013年时,为了更深入地学习研究中间件框架,转到了蚂蚁金服中间件团队,从那个时候开始就一直在做 SOFA。 目前鲁直在SOFA的团队主要负责的工作包括几个部分。其中一个主要部分就是 SOFA 开源相关的工作。SOFA 的产品体系非常广,包括已经对外开源的部分、内部整个微服务体系,以及 SOFA 框架等等——而这些开源相关的工作主要是由鲁直负责推动的。 当然,作为技术负责人,鲁直既要带技术团队也要做技术工作。谈及这一点,鲁直说: “我觉得做技术管理,跟普通的管理不太一样,因为技术管理最重要的一个点是除了管理之外,还要保持一定的技术判断力和敏锐度。对一些新技术,包括团队中遇到一些重大的技术问题,你都要有一些方向性的判断。虽然最后不一定是你具体解决的,但是在整个团队的技术攻坚和技术选型上,要一起确立方向。” 我以前也做过十余年的技术管理,我很能够感受这种情况,重大问题技术负责人更要迎难而上。 SOFA 5 落子 Service Mesh就我了解的情况,现在 SOFA 已经发展到了 SOFA5 了。在 SOFA4阶段,主要的任务是将开源体系捋清楚了,然后开始按步骤地开源;到现在发展到了 SOFA5。我想知道从 SOFA4 发展到 SOFA5,是什么让蚂蚁金服中间件团队判断 SOFA4 的阶段性目标已经达成,可以迈进到新的 SOFA5 阶段了呢? “从整个业界趋势上来讲,SOFA4 的架构相对来说还是偏传统一些,更多是对我们之前的技术框架的整理和梳理。在这个阶段,SOFA 的代码经过了非常多的优化和重构,才达到了对外开源的要求,从而 SOFA 走上了开源核心的模式,逐步分阶段的将各个部分进行了开源。”鲁直讲到,“但是,从我们对业界的整体判断上来说,未来无疑是云的时代,所以说要考虑怎么让所有的业务系统能够提供云的能力,比如说 Serverless。” 接着这个话题,鲁直讲了他对云计算的理解:“一方面云计算肯定要为整个业务的发展提供更加方便的基础资源,可以不用去关心底层的基础设施。Serverless字面的意思就是说‘无服务器’——我不用关心服务器怎么来的,不用关心基础设施,只要关心业务代码就可以了。那反过来对于云服务商来说,经过了这一层抽象,其资源利用率会更高,可以有更多的利润空间,这是一个双赢的局面。对于用户来讲,这种好处是实实在在的,可以更少关注基础设施,只关心代码就可以了。” “我们希望在 SOFA5 的方向上,在这个新的迭代中,去让业务——包括让未来我们开源出来各种功能、各样服务模式——都更多地去关心自己的业务代码,而不用再过多地关心基础设施。”鲁直说, 在 SOFA5 中,一个重要的方向就是 Service Mesh这个方向,这将是 SOFA5 中非常重要的特性。鲁直强调了其对 Service Mesh 技术的看好:“我认为 Service Mesh 是迈向未来往前走的非常关键的一步,让业务不用再关心基础设施。通过 Service Mesh,我们可以将很多技术能力直接放到基础设施里面,而业务可以不用感知到这一层。原来可能需要花几个小时或者更多的时间解决的基础设施问题,现在可以通过 Service Mesh解决掉。” ...

April 30, 2019 · 2 min · jiezi

阿里新一代分布式任务调度平台Schedulerx20破土而出

1. 产品简介Schedulerx2.0是阿里中间件自研的基于Akka架构的新一代分布式任务调度平台,提供定时、任务编排、分布式跑批等功能。使用Schedulerx2.0,您可以在控制台配置管理您的定时任务,查询历史执行记录,查看运行日志。借助Schedulerx2.0,您还可以通过工作流进行任务编排和数据传递。Schedulerx2.0还提供了简单易用的分布式编程模型,简单几行代码就可以将海量数据分布式到多台机器上执行。 Schedulerx2.0提供了任务调度与执行的一整套解决方案,在阿里巴巴集团内部广泛使用并久经考验,具有高可靠、海量任务、秒级别调度等能力。 上线时间:2019-04-30 2. 背景Schedulerx2.0是Schedulerx1.0(DTS)的下一代产品,采用全新的架构,是全新自研的下一代分布式任务调度平台,不但解决了老产品的性能瓶颈,还提供了更多更快更强的能力。 更多:支持多种时间表达式,任务编排,支持更多的业务场景。单集群支持上千万任务,一天上十亿次调度,支持更多的任务数。更快:支持秒级别调度,处理准实时业务。更强:支持日志查询、原地重跑、重刷数据等多种操作,提供更强的运维能力和排错手段,解决为什么没跑,为什么失败,为什么跑得慢等问题。3. 功能3.1 强大的定时调度器3.1.1 Crontab 支持unix crontab表达式,不支持秒级别。 3.1.2 Fixed rate 众所周知,crontab必须被60整除,比如想每隔40分钟跑一次,cron不支持。Fixed rate专门用来做定期轮询,表达式简单,不支持秒级别。 3.1.3 Fixed delay 适合对实时性要求比较高的业务,比如每次执行完成隔10秒再跑,那么second delay非常适合你。并且second delay能支持到秒级别。 3.1.4 日历 支持多种日历,还可以自定义导入日历。比如金融业务需要在每个交易日执行。 3.1.5 时区 跨国的业务,需要在每个国家的时区定时执行某个任务。 3.2 任务编排支持工作流(DAG)进行任务编排,操作简单,前端直接单手操作拖拖拽拽即可。详细的任务状态图能一目了然看到下游任务为什么没跑。 3.3 任务类型支持多种任务类型,可以无限扩展。 java:可以跑在用户进程中,也可以上传jar包动态加载。shell:前端直接写shell脚本。python:前端直接写python脚本,需要机器有python环境。go:前端直接写go脚本,需要机器有go环境。自定义:用户甚至可以自定义任务类型,然后实现一个plugin就行了。3.4 执行方式&分布式编程模型3.4.1 执行方式 单机:随机挑选一台机器执行广播:所有机器同时执行且等待全部结束并行计算:map/mapreduce模型,1~300个子任务,有子任务列表。内存网格:map/mapreduce模型,10W以下子任务,无子任务列表,基于内存计算,比网格计算快。网格计算:map/mapreduce模型,100W以下子任务,无子任务列表,基于文件H2计算。3.4.2 分布式编程模型 Map模型:类似于hadoop mapreduce里的map。只要实现一个map方法,简单几行代码就可以将海量数据分布式到客户自己的多台机器上执行,进行跑批。MapReduce模型:MapReduce模型是Map模型的扩展,新增reduce接口,所有子任务完成后会执行reduce方法,可以在reduce方法中返回该任务实例的执行结果,或者回调业务。3.5 强大的运维能力数据大盘:控制台提供了执行记录大盘和执行列表,可以看到每个任务的执行历史,并提供操作。查看日志:每条执行记录,都可以详情中的日志页面实时看到日志。如果任务运行失败了,前端直接就能看到错误日志,非常方便。原地重跑:任务失败,修改完代码发布后,可以点击原地重跑。标记成功:任务失败,如果后台把数据处理正确了,重跑又需要好几个小时,直接标记成功就好了。Kill:实现JobProcessor的kill()接口,你就可以在前端kill正在运行的任务,甚至子任务。3.6 数据时间Schedulerx2.0可以处理有数据状态的任务。创建任务的时候可以填数据偏移。比如一个任务是每天00:30运行,但是实际上要处理上一天的数据,就可以向前偏移一个小时。运行时间不变,执行的时候通过context.getDataTime()获得的就是前一天23:30。 3.7 重刷数据既然任务具有了数据时间,一定少不了重刷数据。比如一个任务/工作流最终产生一个报表,但是业务发生变更(新增一个字段),或者发现上一个月的数据都有错误,那么就需要重刷过去一个月的数据。 通过重刷数据功能,可以重刷某些任务/工作流的数据(只支持天级别),每个实例都是不同的数据时间。 3.8 失败自动重试实例失败自动重试:在任务管理的高级配置中,可以配置实例失败重试次数和重试间隔,比如重试3次,每次间隔30秒。如果重试3次仍旧失败,该实例状态才会变为失败,并发送报警。子任务失败自动重试:如果是分布式任务(并行计算/内网网格/网格计算),子任务也支持失败自动重试和重试间隔,同样可以通过任务管理的高级配置进行配置。3.9 支持原生Spring之前的老产品Schedulerx1.0(DTS)和spring的结合非常暴力,对bean的命名有强要求,经常遇到注入失败的问题。Schedulerx2.0支持原生spring语法,接入更加的方便。 3.10 报警监控失败报警超时报警报警方式:短信 本文作者:黄晓萌阅读原文 本文为云栖社区原创内容,未经允许不得转载。

April 24, 2019 · 1 min · jiezi

Fish Redux中的Dispatch是怎么实现的?

零、前言我们在使用fish-redux构建应用的时候,界面代码(view)和事件的处理逻辑(reducer,effect)是完全解耦的,界面需要处理事件的时候将action分发给对应的事件处理逻辑去进行处理,而这个分发的过程就是下面要讲的dispatch, 通过本篇的内容,你可以更深刻的理解一个action是如何一步步去进行分发的。一、从example开始为了更好的理解action的dispatch过程,我们就先以todo_list_page中一条todo条目的勾选事件为例,来看点击后事件的传递过程,通过断点debug我们很容易就能够发现点击时候发生的一切,具体过程如下:用户点击勾选框,GestureDetector的onTap会被回调通过buildView传入的dispatch函数对doneAction进行分发,发现todo_component的effect中无法处理此doneAction,所以将其交给pageStore的dispatch继续进行分发pageStore的dispatch会将action交给reducer进行处理,故doneAction对应的_markDone会被执行,对state进行clone,并修改clone后的state的状态,然后将这个全新的state返回然后pageStore的dispatch会通知所有的listeners,其中负责界面重绘的_viewUpdater发现state发生变化,通知界面进行重绘更新二、Dispatch实现分析Dispatch在实现的过程中借鉴了Elm。Dispatch在fish-redux中的定义如下typedef Dispatch = void Function(Action action);本质上就是一个action的处理函数,接受一个action,然后对action进行分发。下面我门通过源码来进行详细的分析1.component中的dispatchbuildView函数传入的dispatch是对应的component的mainCtx中的dispatch,_mainCtx和componet的关系如下component -> ComponentWidget -> ComponentState -> _mainCtx -> _dispatch而 _mainCtx的初始化则是通过componet的createContext方法来创建的,顺着方法下去我们看到了dispatch的初始化// redux_component/context.dart DefaultContext初始化方法 DefaultContext({ @required this.factors, @required this.store, @required BuildContext buildContext, @required this.getState, }) : assert(factors != null), assert(store != null), assert(buildContext != null), assert(getState != null), _buildContext = buildContext { final OnAction onAction = factors.createHandlerOnAction(this); /// create Dispatch _dispatch = factors.createDispatch(onAction, this, store.dispatch); /// Register inter-component broadcast _onBroadcast = factors.createHandlerOnBroadcast(onAction, this, store.dispatch); registerOnDisposed(store.registerReceiver(_onBroadcast)); }context中的dispatch是通过factors来进行创建的,factors其实就是当前component,factors创建dispatch的时候传入了onAction函数,以及context自己和store的dispatch。onAction主要是进行Effect处理。这边还可以看到,进行context初始化的最后,还将自己的onAction包装注册到store的广播中去,这样就可以接收到别人发出的action广播。Component继承自Logic// redux_component/logic.dart @override Dispatch createDispatch( OnAction onAction, Context<T> ctx, Dispatch parentDispatch) { Dispatch dispatch = (Action action) { throw Exception( ‘Dispatching while appending your effect & onError to dispatch is not allowed.’); }; /// attach to store.dispatch dispatch = _applyOnAction<T>(onAction, ctx)( dispatch: (Action action) => dispatch(action), getState: () => ctx.state, )(parentDispatch); return dispatch; } static Middleware<T> _applyOnAction<T>(OnAction onAction, Context<T> ctx) { return ({Dispatch dispatch, Get<T> getState}) { return (Dispatch next) { return (Action action) { final Object result = onAction?.call(action); if (result != null && result != false) { return; } //skip-lifecycle-actions if (action.type is Lifecycle) { return; } if (!shouldBeInterruptedBeforeReducer(action)) { ctx.pageBroadcast(action); } next(action); }; }; }; }}上面分发的逻辑大概可以通过上图来表示通过onAction将action交给component对应的effect进行处理当effect无法处理此action,且此action非lifecycle-actions,且不需中断则广播给当前Page的其余所有effects最后就是继续将action分发给store的dispatch(parentDispatch传入的其实就是store.dispatch)2. store中的dispatch从store的创建代码我们可以看到store的dispatch的具体逻辑// redux/create_store.dart final Dispatch dispatch = (Action action) { _throwIfNot(action != null, ‘Expected the action to be non-null value.’); _throwIfNot( action.type != null, ‘Expected the action.type to be non-null value.’); _throwIfNot(!isDispatching, ‘Reducers may not dispatch actions.’); try { isDispatching = true; state = reducer(state, action); } finally { isDispatching = false; } final List<_VoidCallback> _notifyListeners = listeners.toList( growable: false, ); for (_VoidCallback listener in _notifyListeners) { listener(); } notifyController.add(state); };store的dispatch过程比较简单,主要就是进行reducer的调用,处理完成后通知监听者。3.middlewarePage继承自Component,增加了middleware机制,fish-redux的redux部分本身其实就对middleware做了支持,可以通过StoreEnhancer的方式将middlewares进行组装,合并到Store的dispatch函数中。middleware机制可以允许我们通过中间件的方式对redux的state做AOP处理,比如fish-redux自带的logMiddleware,可以对state的变化进行log,分别打印出state变化前和变化后的值。当Page配置了middleware之后,在创建pageStore的过程中会将配置的middleware传入,传入之后会对store的dispath进行增强加工,将middleware的处理函数串联到dispatch中。// redux_component/component.dart Widget buildPage(P param) { return wrapper(_PageWidget<T>( component: this, storeBuilder: () => createPageStore<T>( initState(param), reducer, applyMiddleware<T>(buildMiddleware(middleware)), ), )); }// redux_component/page_store.dartPageStore<T> createPageStore<T>(T preloadedState, Reducer<T> reducer, [StoreEnhancer<T> enhancer]) => _PageStore<T>(createStore(preloadedState, reducer, enhancer));// redux/create_store.dartStore<T> createStore<T>(T preloadedState, Reducer<T> reducer, [StoreEnhancer<T> enhancer]) => enhancer != null ? enhancer(_createStore)(preloadedState, reducer) : _createStore(preloadedState, reducer);所以这里可以看到,当传入enhancer时,createStore的工作被enhancer代理了,会返回一个经过enhancer处理过的store。而PageStore创建的时候传入的是中间件的enhancer。// redux/apply_middleware.dartStoreEnhancer<T> applyMiddleware<T>(List<Middleware<T>> middleware) { return middleware == null || middleware.isEmpty ? null : (StoreCreator<T> creator) => (T initState, Reducer<T> reducer) { assert(middleware != null && middleware.isNotEmpty); final Store<T> store = creator(initState, reducer); final Dispatch initialValue = store.dispatch; store.dispatch = (Action action) { throw Exception( ‘Dispatching while constructing your middleware is not allowed. ’ ‘Other middleware would not be applied to this dispatch.’); }; store.dispatch = middleware .map((Middleware<T> middleware) => middleware( dispatch: (Action action) => store.dispatch(action), getState: store.getState, )) .fold( initialValue, (Dispatch previousValue, Dispatch Function(Dispatch) element) => element(previousValue), ); return store; };}这里的逻辑其实就是将所有的middleware的处理函数都串到store的dispatch,这样当store进行dispatch的时候所有的中间件的处理函数也会被调用。下面为各个处理函数的执行顺序,首先还是component中的dispatch D1 会被执行,然后传递给store的dispatch,而此时store的dispatch已经经过中间件的增强,所以会执行中间件的处理函数,最终store的原始dispatch函数D2会被执行。三、总结通过上面的内容,现在我们可以知道一个action是如何一步步的派送给effect,reducer去进行处理的,我们也可以通过middleware的方式去跟踪state的变化,这样的扩展性给框架本身带来无限可能。本文作者:闲鱼技术-卢克阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

April 17, 2019 · 2 min · jiezi

有赞百亿级日志系统架构设计

一、概述日志是记录系统中各种问题信息的关键,也是一种常见的海量数据。日志平台为集团所有业务系统提供日志采集、消费、分析、存储、索引和查询的一站式日志服务。主要为了解决日志分散不方便查看、日志搜索操作复杂且效率低、业务异常无法及时发现等等问题。随着有赞业务的发展与增长,每天都会产生百亿级别的日志量(据统计,平均每秒产生 50 万条日志,峰值每秒可达 80 万条)。日志平台也随着业务的不断发展经历了多次改变和升级。本文跟大家分享有赞在当前日志系统的建设、演进以及优化的经历,这里先抛砖引玉,欢迎大家一起交流讨论。二、原有日志系统有赞从 16 年就开始构建适用于业务系统的统一日志平台,负责收集所有系统日志和业务日志,转化为流式数据,通过 flume 或者 logstash 上传到日志中心(kafka 集群),然后共 Track、Storm、Spark 及其它系统实时分析处理日志,并将日志持久化存储到 HDFS 供离线数据分析处理,或写入 ElasticSearch 提供数据查询。整体架构如下图 所示。随着接入的应用的越来越多,接入的日志量越来越大,逐渐出现一些问题和新的需求,主要在以下几个方面:1.业务日志没有统一的规范,业务日志格式各式各样,新应用接入无疑大大的增加了日志的分析、检索成本。2.多种数据日志数据采集方式,运维成本较高3.存储方面,-采用了 Es 默认的管理策略,所有的 index 对应 3*2个shard(3 个 primary,3 个 replica),有部分 index 数量较大,对应单个 shard 对应的数据量就会很大,导致有 hot node,出现很多 bulk request rejected,同时磁盘 IO 集中在少数机器上。-对于 bulk request rejected 的日志没有处理,导致业务日志丢失-日志默认保留 7 天,对于 ssd 作为存储介质,随着业务增长,存储成本过于高昂-另外 Elasticsearch 集群也没有做物理隔离,Es 集群 oom 的情况下,使得集群内全部索引都无法正常工作,不能为核心业务运行保驾护航4.日志平台收集了大量用户日志信息,当时无法直接的看到某个时间段,哪些错误信息较多,增加定位问题的难度。三、现有系统演进日志从产生到检索,主要经历以下几个阶段:采集->传输->缓冲->处理->存储->检索,详细架构如下图所示:3.1日志接入日志接入目前分为两种方式,SDK 接入和调用 Http Web 服务接入-SDK 接入:日志系统提供了不同语言的 SDK,SDK 会自动将日志的内容按照统一的协议格式封装成最终的消息体,并最后最终通过 TCP 的方式发送到日志转发层(rsyslog-hub)-Http Web 服务接入:有些无法使用 SDk 接入日志的业务,可以通过 Http 请求直接发送到日志系统部署的 Web 服务,统一由 web protal 转发到日志缓冲层的 kafka 集群3.2日志采集现在有 rsyslog-hub 和 web portal 做为日志传输系统,rsyslog 是一个快速处理收集系统日志的程序,提供了高性能、安全功能和模块化设计。之前系统演进过程中使用过直接在宿主机上部署 flume 的方式,由于 flume 本身是 java 开发的,会比较占用机器资源而统一升级为使用 rsyslog 服务。为了防止本地部署与 kafka 客户端连接数过多,本机上的 rsyslog 接收到数据后,不做过多的处理就直接将数据转发到 rsyslog-hub 集群,通过 LVS 做负载均衡,后端的 rsyslog-hub 会通过解析日志的内容,提取出需要发往后端的 kafka topic。3.3日志缓冲Kafka 是一个高性能、高可用、易扩展的分布式日志系统,可以将整个数据处理流程解耦,将 kafka 集群作为日志平台的缓冲层,可以为后面的分布式日志消费服务提供异步解耦、削峰填谷的能力,也同时具备了海量数据堆积、高吞吐读写的特性。3.4日志切分日志分析是重中之重,为了能够更加快速、简单、精确地处理数据。日志平台使用 spark streaming 流计算框架消费写入 kafka 的业务日志,Yarn 作为计算资源分配管理的容器,会跟不同业务的日志量级,分配不同的资源处理不同日志模型。整个 spark 任务正式运行起来后,单个批次的任务会将拉取的到所有的日志分别异步的写入到 ES 集群。业务接入之前可以在管理台对不同的日志模型设置任意的过滤匹配的告警规则,spark 任务每个 excutor 会在本地内存里保存一份这样的规则,在规则设定的时间内,计数达到告警规则所配置的阈值后,通过指定的渠道给指定用户发送告警,以便及时发现问题。当流量突然增加,es 会有 bulk request rejected 的日志会重新写入 kakfa,等待补偿。3.5日志存储-原先所有的日志都会写到 SSD 盘的 ES 集群,logIndex 直接对应 ES 里面的索引结构,随着业务增长,为了解决 Es 磁盘使用率单机最高达到 70%80% 的问题,现有系统采用 Hbase 存储原始日志数据和 ElasticSearch 索引内容相结合的方式,完成存储和索引。-Index 按天的维度创建,提前创建index会根据历史数据量,决定创建明日 index 对应的 shard 数量,也防止集中创建导致数据无法写入。现在日志系统只存近 7 天的业务日志,如果配置更久的保存时间的,会存到归档日志中。-对于存储来说,Hbase、Es 都是分布式系统,可以做到线性扩展。四、多租户随着日志系统不断发展,全网日志的 QPS 越来越大,并且部分用户对日志的实时性、准确性、分词、查询等需求越来越多样。为了满足这部分用户的需求,日志系统支持多租户的的功能,根据用户的需求,分配到不同的租户中,以避免相互影响。 针对单个租户的架构如下:-SDK:可以根据需求定制,或者采用天网的 TrackAppender 或 SkynetClient-Kafka 集群:可以共用,也可以使用指定 Kafka 集群-Spark 集群:目前的 Spark 集群是在 yarn 集群上,资源是隔离的,一般情况下不需要特地做隔离-存储:包含 ES 和 Hbase,可以根据需要共用或单独部署 ES 和 Hbase五、现有问题和未来规划目前,有赞日志系统作为集成在天网里的功能模块,提供简单易用的搜索方式,包括时间范围查询、字段过滤、NOT/AND/OR、模糊匹配等方式,并能对查询字段高亮显示,定位日志上下文,基本能满足大部分现有日志检索的场景,但是日志系统还存在很多不足的地方,主要有:1.缺乏部分链路监控:日志从产生到可以检索,经过多级模块,现在采集,日志缓冲层还未串联,无法对丢失情况进行精准监控,并及时推送告警。2.现在一个日志模型对应一个 kafka topic,topic 默认分配三个 partition,由于日志模型写入日志量上存在差异,导致有的 topic 负载很高,有的 topic 造成一定的资源浪费,且不便于资源动态伸缩。topic 数量过多,导致 partition 数量过多,对 kafka 也造成了一定资源浪费,也会增加延迟和 Broker 宕机恢复时间。3.目前 Elasticsearch 中文分词我们采用 ik_max_word,分词目标是中文,会将文本做最细粒度的拆分,但是日志大部分都是英文,分词效果并不是很好。上述的不足之处也是我们以后努力改进的地方,除此之外,对于日志更深层次的价值挖掘也是我们探索的方向,从而为业务的正常运行保驾护航。4月27日(周六)下午13:30,有赞技术中间件团队联合Elastic中文社区,围绕Elastic的开源产品及周边技术,在杭州举办一场线下技术交流活动。本次活动免费开放,限额200名。扫描下图二维码,回复“报名”即可参加欢迎参加,我们一起聊聊 ...

April 15, 2019 · 1 min · jiezi

干货|Spring Cloud Stream 体系及原理介绍

Spring Cloud Stream 在 Spring Cloud 体系内用于构建高度可扩展的基于事件驱动的微服务,其目的是为了简化消息在 Spring Cloud 应用程序中的开发。Spring Cloud Stream (后面以 SCS 代替 Spring Cloud Stream) 本身内容很多,而且它还有很多外部的依赖,想要熟悉 SCS,必须要先了解 Spring Messaging 和 Spring Integration 这两个项目,接下来文章将从以下几点跟大家进行介绍:什么是 Spring Messaging;什么是 Spring Integration;什么是 SCS及其功能;Spring MessagingSpring Messaging 是 Spring Framework 中的一个模块,其作用就是统一消息的编程模型。比如消息 Messaging 对应的模型就包括一个消息体 Payload 和消息头 Header:package org.springframework.messaging;public interface Message<T> { T getPayload(); MessageHeaders getHeaders();}消息通道 MessageChannel 用于接收消息,调用 send 方法可以将消息发送至该消息通道中 :@FunctionalInterfacepublic interface MessageChannel { long INDEFINITE_TIMEOUT = -1; default boolean send(Message<?> message) { return send(message, INDEFINITE_TIMEOUT); } boolean send(Message<?> message, long timeout);}消息通道里的消息如何被消费呢?由消息通道的子接口可订阅的消息通道 SubscribableChannel 实现,被 MessageHandler 消息处理器所订阅:public interface SubscribableChannel extends MessageChannel { boolean subscribe(MessageHandler handler); boolean unsubscribe(MessageHandler handler);}由MessageHandler 真正地消费/处理消息:@FunctionalInterfacepublic interface MessageHandler { void handleMessage(Message<?> message) throws MessagingException;}Spring Messaging 内部在消息模型的基础上衍生出了其它的一些功能,如:消息接收参数及返回值处理:消息接收参数处理器 HandlerMethodArgumentResolver 配合 @Header, @Payload 等注解使用;消息接收后的返回值处理器 HandlerMethodReturnValueHandler 配合 @SendTo 注解使用;消息体内容转换器 MessageConverter;统一抽象的消息发送模板 AbstractMessageSendingTemplate;消息通道拦截器 ChannelInterceptor;Spring IntegrationSpring Integration 提供了 Spring 编程模型的扩展用来支持企业集成模式(Enterprise Integration Patterns),是对 Spring Messaging 的扩展。它提出了不少新的概念,包括消息的路由 MessageRoute、消息的分发 MessageDispatcher、消息的过滤 Filter、消息的转换 Transformer、消息的聚合 Aggregator、消息的分割 Splitter 等等。同时还提供了 MessageChannel 和MessageHandler 的实现,分别包括 DirectChannel、ExecutorChannel、PublishSubscribeChannel 和MessageFilter、ServiceActivatingHandler、MethodInvokingSplitter 等内容。首先为大家介绍几种消息的处理方式:消息的分割:消息的聚合:消息的过滤:消息的分发:接下来,我们以一个最简单的例子来尝试一下 Spring Integration:SubscribableChannel messageChannel = new DirectChannel(); // 1messageChannel.subscribe(msg -> { // 2 System.out.println(“receive: " + msg.getPayload());});messageChannel.send(MessageBuilder.withPayload(“msg from alibaba”).build()); // 3构造一个可订阅的消息通道 messageChannel;使用 MessageHandler 去消费这个消息通道里的消息;发送一条消息到这个消息通道,消息最终被消息通道里的 MessageHandler 所消费,最后控制台打印出: receive: msg from alibaba;DirectChannel 内部有个 UnicastingDispatcher 类型的消息分发器,会分发到对应的消息通道 MessageChannel 中,从名字也可以看出来,UnicastingDispatcher 是个单播的分发器,只能选择一个消息通道。那么如何选择呢? 内部提供了 LoadBalancingStrategy 负载均衡策略,默认只有轮询的实现,可以进行扩展。我们对上段代码做一点修改,使用多个 MessageHandler 去处理消息:SubscribableChannel messageChannel = new DirectChannel();messageChannel.subscribe(msg -> { System.out.println(“receive1: " + msg.getPayload());});messageChannel.subscribe(msg -> { System.out.println(“receive2: " + msg.getPayload());});messageChannel.send(MessageBuilder.withPayload(“msg from alibaba”).build());messageChannel.send(MessageBuilder.withPayload(“msg from alibaba”).build());由于 DirectChannel 内部的消息分发器是 UnicastingDispatcher 单播的方式,并且采用轮询的负载均衡策略,所以这里两次的消费分别对应这两个 MessageHandler。控制台打印出:receive1: msg from alibabareceive2: msg from alibaba既然存在单播的消息分发器 UnicastingDispatcher,必然也会存在广播的消息分发器,那就是 BroadcastingDispatcher,它被 PublishSubscribeChannel 这个消息通道所使用。广播消息分发器会把消息分发给所有的 MessageHandler:SubscribableChannel messageChannel = new PublishSubscribeChannel();messageChannel.subscribe(msg -> { System.out.println(“receive1: " + msg.getPayload());});messageChannel.subscribe(msg -> { System.out.println(“receive2: " + msg.getPayload());});messageChannel.send(MessageBuilder.withPayload(“msg from alibaba”).build());messageChannel.send(MessageBuilder.withPayload(“msg from alibaba”).build());发送两个消息,都被所有的 MessageHandler 所消费。控制台打印:receive1: msg from alibabareceive2: msg from alibabareceive1: msg from alibabareceive2: msg from alibabaSpring Cloud StreamSCS与各模块之间的关系是:SCS 在 Spring Integration 的基础上进行了封装,提出了 Binder, Binding, @EnableBinding, @StreamListener 等概念;SCS 与 Spring Boot Actuator 整合,提供了 /bindings, /channels endpoint;SCS 与 Spring Boot Externalized Configuration 整合,提供了 BindingProperties, BinderProperties 等外部化配置类;SCS 增强了消息发送失败的和消费失败情况下的处理逻辑等功能。SCS 是 Spring Integration 的加强,同时与 Spring Boot 体系进行了融合,也是 Spring Cloud Bus 的基础。它屏蔽了底层消息中间件的实现细节,希望以统一的一套 API 来进行消息的发送/消费,底层消息中间件的实现细节由各消息中间件的 Binder 完成。Binder 是提供与外部消息中间件集成的组件,为构造 Binding提供了 2 个方法,分别是 bindConsumer 和 bindProducer ,它们分别用于构造生产者和消费者。目前官方的实现有 Rabbit Binder 和 Kafka Binder, Spring Cloud Alibaba 内部已经实现了 RocketMQ Binder。从图中可以看出,Binding 是连接应用程序跟消息中间件的桥梁,用于消息的消费和生产。我们来看一个最简单的使用 RocketMQ Binder 的例子,然后分析一下它的底层处理原理:启动类及消息的发送:@SpringBootApplication@EnableBinding({ Source.class, Sink.class }) // 1public class SendAndReceiveApplication { public static void main(String[] args) { SpringApplication.run(SendAndReceiveApplication.class, args); } @Bean // 2 public CustomRunner customRunner() { return new CustomRunner(); } public static class CustomRunner implements CommandLineRunner { @Autowired private Source source; @Override public void run(String… args) throws Exception { int count = 5; for (int index = 1; index <= count; index++) { source.output().send(MessageBuilder.withPayload(“msg-” + index).build()); // 3 } } }}消息的接收:@Servicepublic class StreamListenerReceiveService { @StreamListener(Sink.INPUT) // 4 public void receiveByStreamListener1(String receiveMsg) { System.out.println(“receiveByStreamListener: " + receiveMsg); }}这段代码很简单,没有涉及到 RocketMQ 相关的代码,消息的发送和接收都是基于 SCS 体系完成的。如果想切换成 RabbitMQ 或 kafka,只需修改配置文件即可,代码无需修改。我们分析这段代码的原理:@EnableBinding 对应的两个接口属性 Source 和 Sink 是 SCS 内部提供的。SCS 内部会基于 Source 和 Sink 构造 BindableProxyFactory,且对应的 output 和 input 方法返回的 MessageChannel 是 DirectChannel。output 和 input 方法修饰的注解对应的 value 是配置文件中 binding 的 name。public interface Source { String OUTPUT = “output”; @Output(Source.OUTPUT) MessageChannel output();}public interface Sink { String INPUT = “input”; @Input(Sink.INPUT) SubscribableChannel input();}配置文件里 bindings 的 name 为 output 和 input,对应 Source 和 Sink 接口的方法上的注解里的 value:spring.cloud.stream.bindings.output.destination=test-topicspring.cloud.stream.bindings.output.content-type=text/plainspring.cloud.stream.rocketmq.bindings.output.producer.group=demo-groupspring.cloud.stream.bindings.input.destination=test-topicspring.cloud.stream.bindings.input.content-type=text/plainspring.cloud.stream.bindings.input.group=test-group1构造 CommandLineRunner,程序启动的时候会执行 CustomRunner 的 run 方法。调用 Source 接口里的 output 方法获取 DirectChannel,并发送消息到这个消息通道中。这里跟之前 Spring Integration 章节里的代码一致。Source 里的 output 发送消息到 DirectChannel 消息通道之后会被 AbstractMessageChannelBinder#SendingHandler 这个 MessageHandler 处理,然后它会委托给 AbstractMessageChannelBinder#createProducerMessageHandler 创建的 MessageHandler 处理(该方法由不同的消息中间件实现);不同的消息中间件对应的 AbstractMessageChannelBinder#createProducerMessageHandler 方法返回的 MessageHandler 内部会把 Spring Message 转换成对应中间件的 Message 模型并发送到对应中间件的 broker;使用 @StreamListener 进行消息的订阅。请注意,注解里的 Sink.input 对应的值是 “input”,会根据配置文件里 binding 对应的 name 为 input 的值进行配置:不同的消息中间件对应的 AbstractMessageChannelBinder#createConsumerEndpoint 方法会使用 Consumer 订阅消息,订阅到消息后内部会把中间件对应的 Message 模型转换成 Spring Message;消息转换之后会把 Spring Message 发送至 name 为 input 的消息通道中;@StreamListener 对应的 StreamListenerMessageHandler 订阅了 name 为 input 的消息通道,进行了消息的消费;这个过程文字描述有点啰嗦,用一张图总结一下(黄色部分涉及到各消息中间件的 Binder 实现以及 MQ 基本的订阅发布功能):SCS 章节的最后,我们来看一段 SCS 关于消息的处理方式的一段代码:@StreamListener(value = Sink.INPUT, condition = “headers[‘index’]==‘1’")public void receiveByHeader(Message msg) { System.out.println(“receive by headers[‘index’]==‘1’: " + msg);}@StreamListener(value = Sink.INPUT, condition = “headers[‘index’]==‘9999’")public void receivePerson(@Payload Person person) { System.out.println(“receive Person: " + person);}@StreamListener(value = Sink.INPUT)public void receiveAllMsg(String msg) { System.out.println(“receive allMsg by StreamListener. content: " + msg);}@StreamListener(value = Sink.INPUT)public void receiveHeaderAndMsg(@Header(“index”) String index, Message msg) { System.out.println(“receive by HeaderAndMsg by StreamListener. content: " + msg);}有没有发现这段代码跟 Spring MVC Controller 中接收请求的代码很像? 实际上他们的架构都是类似的,Spring MVC 对于 Controller 中参数和返回值的处理类分别是 org.springframework.web.method.support.HandlerMethodArgumentResolver、 org.springframework.web.method.support.HandlerMethodReturnValueHandler。Spring Messaging 中对于参数和返回值的处理类之前也提到过,分别是 org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver、org.springframework.messaging.handler.invocation.HandlerMethodReturnValueHandler。它们的类名一模一样,甚至内部的方法名也一样。总结上图是 SCS 体系相关类说明的总结,关于 SCS 以及 RocketMQ Binder 更多相关的示例,可以参考 RocketMQ Binder Demos,包含了消息的聚合、分割、过滤;消息异常处理;消息标签、sql过滤;同步、异步消费等等。下一篇文章,我们将分析消息总线(Spring Cloud Bus) 在 Spring Cloud 体系中的作用,并逐步展开,分析 Spring Cloud Alibaba 中的 RocketMQ Binder 是如何实现 Spring Cloud Stream 标准的。本文作者:中间件小哥阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

April 9, 2019 · 4 min · jiezi

我们总结了每个技术团队都会遇到的 4 个难题

阿里巴巴 2019 年实习生校园招聘已经启动,为此,我们整理了一篇《每个技术团队都会遇到的4个难题》,帮助即将从校园进入公司实习的后端程序员,以实践的视角,看看一个后端技术团队会遇到的一些难题。虽然,技术上的难题远不止于此,但如果能从这篇文章中获得一些职业体感,也许对你的实习面试会有所帮助。- 正文开始 -从单个应用到多个应用,从百千级别的访问流量到十万、百万级别,从两三个人的创业技术团队到上千人的技术团队矩阵,这些过程中,技术团队都避不开了以下 4 个问题:如何预测业务峰值时的容量如何提升业务的稳定性如何提高业务的监控能力如何提高开发效率如何预测业务峰值时的容量早期的做法是在开发测试环境进行压测,来评估线上容量,但线下环境的机器规模,和线上差距很大,很难通过线下推导线上。根据经验,将采购的机器加入不同的应用里面,这时候就会遇到一个问题: 最大业务峰值容量是多少?这个问题,其实挺难回答的。这个应用多加几台,那个应用少加几台,整体的业务峰值承受能力就会不一样,加减的规则很难通过人的经验来确定,最多只能作为一些辅助判断。另外,核心交易链路的梳理,也是一个体力活,如果依赖人为处理,有可能会漏掉一些看起来不那么重要的”分支”,这是整个容量不确定的地方,可变的因子很多。比较有效的方式, 是在生产系统部署全链路压测,来验证各个生产环节是否能经受住各类流量的访问,让真实的流量来访问生产环境,实现全方位的真实业务场景模拟,确保各个环节的性能、容量和稳定性均可做到万无一失。如何提升业务的稳定性日常的各种运营活动,都有可能带来巨大的流量高峰,除了通过引入全链路压测来验证各个生产环节是否能经受住各类流量的访问, 构建系统的高可用保障能力也很关键,涉及多个组件或模块,例如软负载和配置中心、服务接入和调度编排、消息接收和发送、容器和调度、限流和降级 等。运营一次活动,最大的流量峰值是可以预测的,这就是服务的最大接待能力,比如50万笔的交易创建峰值,那超过的怎么办?这时候,采用限流的方式,被限流的客户在某一段时间内无法进行购物,一旦系统恢复服务能力,就可以继续服务被限流的客户,从而避免因流量超过上限,而影响整个平台的客户。如何提高业务的监控能力分布式应用系统在协作性,扩展性和一定的容错性方面,体现出了优势,但是在监控、运维和诊断层面,面临相当大的挑战。早期,架构师可以画出整个应用系统的交互架构图,随着业务的发展,当拥有大量的应用、微服务和容器,即便整理了一幅交互架构关系图,也会因为应用系统的变更,新需求的实现,整个应用系统的交互又会发生变化,这种变化无处不在,每天都在发生。因此,随着业务量的增加,需要覆盖面广且深的全链路跟踪监控系统 ,来诊断调用链的问题。越是复杂的业务形态,定位的难度越大,就越需要全方位、360度无死角的监控,因此,建立一个平台化、跨领域和立体化的监控,能极大的缩短业务遇到问题时的恢复时间。如何提高开发效率开发效率是一个很广泛的话题。不同的开发岗位,不同的使用场景,会有不一样的开发效率工具。这里,我们介绍几款后端工程师经常会用到的效率工具。云端部署效率工具:Cloud Toolkit 是一款 IDE插件,可以帮助开发者更高效地开发、测试、诊断并部署应用。借助这个工具,开发者能够方便地将本地应用一键部署到任意机器,或 ECS、EDAS、Kubernetes,并支持高效执行终端命令和 SQL 等。点此了解详情。MacOS 搜索利器:MacOS 自带的聚焦搜索(Spotlight),可以将文稿、邮件、应用等整合在一起,通过关键词匹配来进行搜索。Alfred 可以看作是Spotlight的增强版,是计算机依赖者的效率神器,支持添加自定义网络搜索引擎,指定规则精准定位本地文件,以及在命令框内使用计算器、词典等实用工具。画图效率工具:系统架构图是为了抽象的表示软件系统的整体轮廓和各个组件之间的相互关系和约束边界,以及软件系统的物理部署和软件系统的演进方向的整体视图。通过架构图,可以让干系人理解、遵循架构决策,就需要把架构信息传递出去。架构图就是一个很好的载体,所谓一图胜千言。点此了解详情。JSON 浏览效率插件对于 JSON 的数据,如果不编排,格式查看起来会很费劲。JSON-handle 是一款对 JSON 格式的内容进行浏览和编辑,以树形图样式展现 JSON 文档的插件,支持实时编辑。Java 代码规约扫描效率插件这是一款 Java 代码规约扫描工具,旨在以工具的手段进行代码规约的落地,项目包含三部分:PMD规则实现、IntelliJ IDEA 插件、Eclipse 插件,帮助开发人员在工程研发的多个阶段进行代码规约检查, 降低故障率、提升编码效率和质量。点此了解详情。当然,除了这些现成的效率工具,提升整个技术团队的开发效率,需要单独开发或改造一些系统,例如团队协作平台、服务化改造等,当你以实习生的身份加入公司后,若有机会参与到这些提升开发效率的项目过程中。由此形成的效率意识,将会影响到你今后的工作习惯和理念。本文作者:中间件小哥阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 14, 2019 · 1 min · jiezi

重磅预告 | 今晚直播:MyCat的坑如何在分布式中间件DBLE上改善

上周,DBLE团队历时3个月准备的开源MySQL分布式中间件DBLE系列公开课发布了,为使社区同学能够更好的评估课程内容、质量以及对DBLE有更清晰深入的认知,我们联合IT168将在第二节课程发布前开放一期直播,跟大家聊聊DBLE与MyCat错综复杂的故事。直播时间:3月14日(今晚)20:00PM分享嘉宾:DBLE项目负责人 蓝寅分享主题:《MyCat的坑如何在分布式中间件DBLE上改善》课程亮点跟你分享MyCat不为人知的一面线上的复杂查询其实结果不对?被MyCat默默吃掉的那些SQL!MyCat不太支持的那些语法!不严谨代码导致的那些bug!内容简介分享将从DBA与研发两个角度进行说明,对于DBA同学最关心的SQL语言实现以及运维管理应当如何评估;开发者同学十分关注的bug修复质量,代码质量及代码科学管理如何判断,通过拆解两方对中间件的需求来吐槽MyCat到底有多少坑以及DBLE是如何避免的,为大家在MySQL的“读写分离”、“分库分表”等架构选型方面提供指引。课程提纲一.DBA角度SQL语言实现 数据查询: 简单查询 / 聚合函数查询 / 函数嵌套查询 / union 查询 / 子查询 / Join查询 / 跨表Join查询 数据操作:Insert / 全局序列 上下文设置:上下文变量运维管理 用户权限:管理端用户权限二.开发角度1.bug修复质量2.代码半成品残留3.代码灌水4.伪造实现直播课程参与方式关注「爱可生开源社区」,回复关键字 “ 直播 ”即可成功报名啦!今晚20:00,一起相约微课堂,关于DBLE公开课或者DBLE的使用问题反馈一键直达DBLE研发团队。开源分布式中间件DBLE社区官网:https://opensource.actionsky….GitHub主页:https://github.com/actiontech…技术交流群:669663113开源数据传输中间件DTLE社区官网:https://opensource.actionsky….GitHub主页:https://github.com/actiontech…技术交流群:852990221

March 14, 2019 · 1 min · jiezi

DBLE核心研发主讲:MySQL分布式中间件公开课开课啦

DBLE年龄:2岁半爱好:开源技能:数据水平拆分、兼容MySQL、高可用性、SQL支持、复杂查询优化、分布式事务支持特长:兼容性、复杂查询、分布式事务的深入改进优化为了使社区同学能够更清晰的了解开源分布式中间件DBLE的功能特性,DBLE核心研发团队历时3个月推出DBLE系列公开课。DBLE公开课简介课程目录DBLE系列课程分为4章,共12节3月15日起,每周五中午11:30前更新课程咨询:DBLE技术交流群(669663113)每天8:30-20:30即时疑问解答适用人群 正在使用DBLE或MyCat的用户当前中间件无法满足业务需求的用户运维大体量数据库,需要考虑分库分表的DBA为数据库架构选型发愁的研发人员讲师介绍▽Attention▽为了让大家更好的了解课程内容以及评估课程质量,本期预热已发布第一期课程,大家可以先感受一下一股强烈的分布式旋风扑面而来是多么清爽。第一章 DBLE的基本使用1.1 DBLE概述课程观看传送门:方式1:打开「爱可生开源社区」官网,点击技术博客,选择DBLE系列公开课即可观看方式2:点击“阅读原文”直达播放现场,一秒开始听课~如何获取课程DBLE系列公开课自3月15日起将按照每周一节课程发布在「爱可生开源社区官网」,点击官网(http://opensource.actionsky.com)博客专栏,即可查看“DBLE系列公开课”。课程免费,公开,我们的最终目标是能有更多的社区同学了解认可并使用DBLE。除此之外,我们为心急的同学提供了新的打开方式:敲黑板:VIP提前解锁新课程朋友圈分享本文并截图给小编(WeChat:mg116611)即可提前2周获取课程,DBLE系列公开课更新结束前分享均有效。

March 9, 2019 · 1 min · jiezi

深度分析 | MyCat与DBLE的对比性能调优

作者简介蓝寅,开源分布式中间件DBLE项目负责人;持续专注于数据库方面的技术, 始终在一线从事开发;对数据复制,读写分离,分库分表的有深入的理解与实践。问题起因:用benchmarksql_for_mysql对原生MyCat-1.6.1和DBLE-2.17.07版做性能测试对比,发现DBLE性能只到原生版MyCat的70%左右。问题分析过程:分析过程主要有以下内容:包括现象,收集数据,分析猜测原因,验证猜测的方式来进行。开源分布式中间件DBLE: 社区官网,获取DBLE快速入门指南及最新资讯: https://opensource.actionsky.com GitHub主页,查看官方文档: https://github.com/actiontech… 社区技术交流群,迅速获取官方支持: QQ群:6696631131.分析瓶颈1.1 先对两者进行一个CPU占用的堆栈分析通过对CPU火焰图的比较,发现DBLE用在纯排序上的CPU占用在15%以上,而MyCat在排序上没有看到明显的CPU占用。( 复盘时的思考:这里有明显的可疑之处,应当及早观察两者是否公平)1.2 首先猜测可能的原因a.由于MyCat对以下这条用例实现有bug:具体方式是直接原句下发SQL到节点,收到各个节点的结果后直接做加法;而DBLE则是改写为select distinct s_i_id 收集全部结果集,然后在中间件做去重和统计的工作。所以两者在这个case上的对比是不公平的。b.排序本身算法选择的问题1.3 对猜测原因的验证a.去除有bug的case,并未看到性能有提升,而且考虑这条用例在所有用例出现的概率只有4%,涉及到的数据也不多,所以应该不是性能问题的主因。b.去除有排序的case,看到两者性能接近,确定是排序的问题。2.猜测原因2.1 猜测一:源码实现原因2.1.1 猜测描述梳理DBLE源码排序逻辑的实现细节,是多路归并的排序,理论上是最优选择。实际上具体的实现上有可优化的空间,如下图, N个数的K路排序的初始化值理论最优复杂度是O(N),而这里变成了O(NlogK2) 。2.1.2 验证猜测为了快速将排序的因素排除,将cmp函数直接返回1再次做测试。结果提升了10%的性能,所以虽然cmp是有性能问题,但导致性能如此大还有其他原因。(复盘:新版本已优化此处10%的性能差异)2.2 猜测二:回到排序SQL查看B-SQL源码,有3个排序SQL,其中有2个排序SQL的排序列不在select 项中,这本来应该引发MyCat的bug的,但我们在返回集和抓包中都没有发现。再仔细阅读源码,原来B-SQL通过hard code的方式使得压力永远跑不到这两个代码路径上,这样我们又排除了2个干扰因素,问题集中到剩下的那个排序上了。将排序除去,64数据量,64并发,DBLE的性能是MyCat的96%。证明确实和排序有关。3.分析多并发压力排序性能的原因3.1 猜测排序算法在特殊场景下的适用性3.1.1 猜测描述由于MyCat排序采用的是timsort, 时间复杂度的可能最优是O(n)。而DBLE的多路归并排序在B-SQL这个场景下时间复杂度最差情况是O(n*(k-1)).猜测timSort排序在B-SQL多并发场景下可能会优于多路归并。3.1.2 验证猜测用B-SQL压测并统计函数调用次数。结论:在B-SQL场景下:两者平均每个排序调用的cmp函数的次数并没有发生明显的异化每个排序cmp次数虽然没有大的差异,但总的调用次数却相差很大,DBLE大约是MyCat的5倍4. 分析DBLE排序时cmp函数次数调用多的原因问题集中在了为什么DBLE会有更多次的比较函数调用。4.1 验证压力下发的SQL是否与cmp函数调用相符是否下发的SQL就不公平4.1.1收集数据用抓包的方式分别抓取B-SQL发给MyCat和DBLE的包,结果发现 DBLE的所有SQL中排序这条SQL的发生次数是MyCat的10倍左右。再次用yourkit查看调用次数和CPU分布验证,发现调用次数确实符合抓包的结论,CPU分布也是DBLE分了大量的时间用于排序,而MyCat对排序的分配几乎可以忽略。这也与最一开始的火焰图结论一样。用wireshark分析DBLE抓包结果,发现某些连接执行一段时间之后大量的重复出现排序+delete的query请求直到压力结束,举例如下图。4.1.2 分析原因分析B-SQL源码这里发现只有delete的数据为0才会引发死循环。4.1.3 验证测试在引发死循环的原因找到之前,先修改代码验证测试。无论result是否是0都设置newOrderRemoved=true使得B-SQL跳出死循环。验证测试,DBLE性能终于符合预期,变为MyCat的105%。至此,B-SQL有排序引发DBLE性能下降的原因找到了,某种场景下B-SQL对DBLE执行delete,影响行数为0,导致此时会有死循环,发送了大量排序请求,严重降低了DBLE性能,并且并发压力越大越容易出现,但也有一定几率不会触发。5.分析哪种场景下delete行数为05.1隔离级别测试因为对隔离级别并不熟悉,花了很长时间才想到原因,在MySQL上做了一个实验:也就是说,在并发情况下确实有可能有死循环出现。5.2 分析为什么只有在DBLE上有这个问题而在MyCat上没有这个问题原因是DBLE和MyCat的默认隔离级别都是REPEATED_READ,但MyCat的实现有bug,除非客户端显式使用set语句,MyCat后端连接使用的隔离级别都是下属结点上的默认隔离级别;而DBLE会在获取后端连接后同步上下文,使得session级别的隔离级别和DBLE配置相同。而后端的四个结点中除了1台是REPEATED_READ,其他三个结点都是READ_COMMITTED。这样同样的并发条件,DBLE100%会触发,而MyCat只有25%的概率触发。5.3 验证测试将DBLE上的配置添加<property name=“txIsolation”>2</property>(默认是3)与默认做对比:性能比是1:0.75.符合期望,性能原因全部找到。6. 吐槽最后吐槽一下B-SQL,找了官方的B-SQL4.1版和5.0版,4.1版并未对此情况做任何改进,仍有可能陷入死循环影响测试。而5.0的对应代码处有这么一段注释,不知道PGSQL是否这里真的会触发异常,但MySQL并不会触发异常,仍有可能陷入死循环。7.性能原因回顾1.cmp函数时候初始化值的问题,影响部分性能,非主要性能瓶颈,新版本已改进。2.同时触发了MyCat和B-SQL的两个bug,导致测试的性能数据负负得正;Mycat bug:配置的隔离级别不生效问题B-SQL bug:RR隔离级别下,delete死循环问题需要将MySQL结点都改为READ_COMMITED,再将配置改为<property name=“txIsolation”>2</property>,避开上述的bug。8.收获1.测试环境的搭建无论是配置参数还是各个节点的状态都要同步,保证公平。2.性能分析工具的使用。3.性能测试可能一次的结果具有偶然性,需要多次验证。4.当有矛盾的结论时候,可能就快接近问题的真相了,需要持续关注。开源分布式中间件DBLE社区官网: https://opensource.actionsky….GitHub主页: https://github.com/actiontech…技术交流群:669663113开源数据传输中间件DTLE社区官网: https://opensource.actionsky….GitHub主页: https://github.com/actiontech…技术交流群:852990221

March 9, 2019 · 1 min · jiezi

使用Grab的实验平台进行混沌实验编排

Roman Atachiants · Tharaka Wijebandara · Abeesh Thomas原文: https://engineering.grab.com/chaos-engineering译:时序背景对每个用户来说,Grab是一个可以叫车,叫外卖或付款的一个APP。对工程师来说,Grab是一个有许多服务并通过RPC交互的分布式系统,有时也可以叫做微服务架构。在数千台服务器上运行的数百个服务每天都有工程师在上面进行变更。每次复杂的配置,事情可能都会变糟。 幸运的是,很多Grab App的内部服务不像用户叫车那样的动作这么重要。例如,收藏夹可以帮用户记住之前的位置,但如果它们不工作,用户仍然可以得到较合理的用户体验。服务部分可用并不是没有风险。工程师需要对于RPC调用非核心服务时需要有有备用计划。如果应急策略没有很好地执行,非核心服务的问题也可能导致停机。所以我们如何保证Grab的用户可以使用核心功能,例如叫车,而此时非核心服务正在出问题?答案是混沌工程。在Grab,我们通过在整体业务流的内部服务或组件上引入故障来实践混沌工程。但失败的服务不是实验的关注点。我们感兴趣的是测试依赖这个失败服务的服务。照理来说,上游服务应该有弹性并且整体业务流应该可以继续工作。比如,叫车流程就算在司机地址服务上出现故障时仍应该可以工作。我们测试重试和降级是否配置正确,是否熔断器被正确的设置。为了将混沌引入我们的系统,我们使用了我们的实验平台(ExP)和Grab-Kit.混沌实验平台Exp将故障注入到处理流量服务的中间件(gRPC或HTTP服务器)。如果系统的行为与期望一致,你将对非核心服务故障时服务会平稳降级产生信心。混沌实验平台ExP在Grab的基础设施中模拟不同的混沌类型,如延迟和内存泄漏。这保证了每个组件在系统的依赖不响应或响应很高时仍能返回一些东西。它能保证我们对于实例级失败有弹性,因为微服务级别的中断对于可用性也是一个威胁。配置混沌实验为了构建我们的混沌工程系统,我们认为需要在两个主要领域引入混沌:基础设置:随机关闭基础设施的实例和其他部分应用: 在较粗粒度引入运行时故障(如endpoint/request级别)你可以稍后启用有意的或随机的混沌实验:随机的比较适合‘一次性’基础设施(如EC2实例)测试冗余的基础设施对最终用户的影响当影响面已经十分确定实验精确度量影响使用实验参数控制对最终用户有限的影响适用于对于影响不十分确定的复杂故障(如延迟)最后,你可以将故障模式按以下分类:资源:CPU,内存,IO,磁盘网络:黑洞,延迟,丢包,DNS状态:关机,时间,杀进程这些模型都可以在基础设施或应用级别使用或模拟:对于Grab,进行应用级别的混沌实验并仔细度量影响面很重要。我们决定使用一个已有的实验平台来对围绕系统的应用级别混沌实验进行编排,即紫色部分,通过对下层像Grab-Kit这样的中间件进行注入来实现。为什么使用实验平台?现在有一些混沌工程工具。但是,使用它们经常需要较高级的基础设施和运维技巧,有能力设计和执行实验,以受控的方式有资源手工编排失败场景。混沌工程不是简单的在生产环境搞破坏。将混沌工程理解成受控的实验。我们的ExP SDK提供弹性和异步追踪。这样,我们可以将潜在的业务属性度量对应到混沌失败上。比如,在订车服务上进行10秒延迟的混沌故障,我们可以知道多少辆车被影响了进而知道损失了多少钱。使用ExP作为混沌工程的工具意味着我们可以基于应用或环境精确定制,让它可以像监控和部署管道一样与其他环境紧密集成。在安全上也可以获得收益。使用ExP,所有的连接都在我们的内部网络中,给我们攻击表面区域的能力。所有东西都可以掌控在手中,对外部世界没有依赖。这也潜在的使监控和控制流量变容易了。混沌故障可以点对点,编程式的,或定期执行。你可以让它们在特定日期的特定时间窗口来执行。你可以设定故障的最大数量并定制它们(比如泄漏的内存MB数量,等待的秒)。ExP的核心价值是让工程师可以启动,控制和观察系统在各种失败条件下的行为。ExP提供全面的故障原子集,用来设计实验并观察问题在复杂分布式系统发生时的表现。而且,将混沌测试集成到ExP,我们对于部署流水线或网络基础设施不需要任何改动。因此这种组合可以很容易的在各种基础设施和部署范式上使用。我们如何打造Chaos SDK和UI要开发混沌工程SDK,我们使用我们已有ExP SDK的属性 - single-digit , 不需要网络调用。你可以看这里对于ExP SDK的实现。现在我们要做两件事:一个在ExP SDK之上的很小的混沌SDK。我们将这个直接集成在我们的已有中间件,如Grab-Kit和DB层。一个专门的用来创建混沌实验的基于web的UI归功于我们与Grab-Kit的集成,Grab工程师不需要直接使用混沌SDK。当Grab-Kit处理进入的请求时,它先使用ExP SDK进行检查。如果请求“应该失败”,它将产生适合的失败类型。然后它被转发到特定endpoint的处理器。我们现在支持以下失败类型:Error - 让请求产生errorCPU Load - 在CPU上加大load内存泄漏 - 产生一些永远不能释放的内存延迟 - 在一小段随机时间内停止请求的处理磁盘空间 - 在机器上填入一些临时文件Goroutine泄漏 - 创建并泄漏goroutinesPanic -限流 - 在请求上设置一个频率限制并在超过限制时拒绝请求举个例子,如果一个叫车请求到了我们的叫车服务,我们调用GetVariable(“chaosFailure”)来决定请求是否应该成功。请求里包含所有需要用来做决定的信息(如请求ID,实例的IP地址等)。关于实验SDK的实现细节,看这篇博客。为了在我们的工程师中推广混沌工程我们围绕它建立了很好的开发者体验。在Grab不同的工程团队会有很多不同的技术和领域。所以一些人可能没有对应的知识和机能来进行合适的混沌实验。但使用我们简化过的用户界面,他们不需要担心底层实现。并且,运行混沌实验的工程师是与像产品分析师和产品经理不同的实验平台用户。所以我们使用一种简单和定制化UI配置新的混沌实验来提供一种不同的创建实验的体验。在混沌工程平台,一个实验有以下四步:定义系统正常情况下的理想状态。创建一个控制组的配置和一个对比组的配置。控制组的变量使用已有值来赋值。对比组的变量使用新值来赋值。引入真实世界的故障,例如增加CPU负载。找到区分系统正确和失败状态标志性不同。要创建一个混沌实验,标明你想要实验破坏的服务。你可以在以后通过提供环境,可用区或实例列表来更细化这个选择范围。下一步,指定一组会被破坏的服务影响的服务列表。你在试验期间需要仔细监控这些服务。尽管我们持续跟踪表示系统健康的整体度量指标,它仍能帮助你在稍后分析实验的影响。然后,我们提供UI来指定目标组和对比组的策略,失败类型,每个对比组的配置。最后一步,提供时间周期并创建实验。你已经在你的系统中加入了混沌故障并可以监控它对系统的影响了。结论在运行混沌实验后,一般会有两种可能输出。你已经确认了在引入的故障中系统保持了足够的弹性,或你发现了需要修复的问题。如果混沌实验最初被运行在预发环境那么两种都是不错的结果。在第一种场景,你对系统的行为产生了信心。在另一个场景,你在导致停机故障前发现了一个问题。混沌工程是让你工作更简单的工具。通过主动测试和验证你系统的故障模式你减轻了你的运维负担,增加了你的弹性,在晚上也能睡个好觉。本文作者:时序阅读原文本文为云栖社区原创内容,未经允许不得转载。

March 6, 2019 · 1 min · jiezi

回顾 | 开源分布式中间件DBLE社区分享活动总结

1月24日,我们发布了为期30天的「如何获取全国 25场 MySQL 主题大会免费入场券」有奖社区分享活动,希望社区同学能够分享测试或生产环境中DBLE使用上的难题,困惑,创新或收获,分享与DBLE相关的社区故事。在经历春节在内的1个月中我们收到共了3位社区同学的4篇投稿,内容涉及DBLE的基础配置系列,DBLE的进阶使用系列,DBLE实际应用案例分析,每篇内容都是社区同学自己在实际应用中的总结与整理,相信这些内容除了与大家分享外更重要的是对产品的具体使用与认知上的沉淀。案例类 社区投稿 | DBLE和MyCat跨分片查询结果不一致案例分析投稿:杨严豪这篇文章的背景是社区同学刚好发现一条跨节点 join 查询在 DBLE、Mycat 的查询得到的结果不一致这样一个比较有意思的场景,于是准备测试环境进行分析比对并最终验证出了正确的数据来源。Tips:故障及案例分析思路可参考,同时提醒同学们重视数据的正确性基础知识类社区投稿 | DBLE rule.xml 配置解析投稿:余朝飞rule.xml 定义实际用到的拆分算法,熟悉各种拆分区算法的详细配置及其适用场景,方便我们在众多数据拆分场景选择并配置合适的拆分规则,同时这也是试用分库分表中间件的第一步。将表的详细拆分算法写在配置中,这是一种很"傻"的方式,但是这也是万不得已的一种选择,如果不通过配置文件的方式告诉中间件这些信息,那么中间件就无从得知底层具体的数据分布情况,也就达不到我们最终想要的目的了。社区投稿 | DBLE Server.xml 配置解析投稿:余朝飞本文简单介绍了Server.xml中的三个重要的配置段落,分别是DBLE的系统配置,用户配置以及黑白名单功能,针对用户配置则介绍了实际应用场景下的配置以及对应的DML权限配置,并详细介绍了DBLE黑白名单配置实践。Tips:以上两篇文章是社区同学在使用DBLE时对具体配置的理解,虽说是基础知识,但认知偏差或粗心大意很可能会为后期埋雷,建议详读,打牢基础。进阶使用类 社区投稿 | DBLE 自定义拆分算法 投稿:钟悦DBLE默认支持数十种数据拆分算法,基本能满足大部分的社区用户的使用需求;为了满足更广的业务场景,DBLE还支持更加灵活的自定义拆分算法;本文对面向有类似需求的DBLE开发者,提供了一个如何开发和部署自定义的拆分规则的一个指引。Tips:此文属于DBLE的进阶使用,为社区提供了DBLE如何开发和部署自定义的拆分规则的一个指引,非常适用于有类似需求的开发者。▽奖励回顾符合活动规则的投稿即可获得 100 RMB 京东E卡经 DBLE 团队审核优质文章可再额外获得:100 RMB 京东E卡在「爱可生开源社区」官微、官网及多个官方自媒体平台的推广展示全国 25场 MySQL主题大会免费入场券(仅限作者本人,不可转让)甲骨文官方MySQL技术交流大会姜承尧老师的IMG社区嘉年华叶金荣&吴炳锡老师的「3306」(包含但不仅限于以上社区活动)▽奖品展示1.「爱可生开源社区」推送的全国25场社区活动免费入场券请3位同学私信小编(wechat:mg116611)领取2.京东E卡(长这样子~)关于以上3位同学200元的京东E卡已发送,预计2个工作日即到;MySQL主题大会免费入场券请私信领取哦。后期我们会继续开放邀请分享,错过的同学请关注下期活动,稿子可以先攒起来~往期精选| 使用指南开源分布式中间件 DBLE 快速入门指南DBLE 自定义拆分算法DBLE Server.xml 配置解析DBLE Schema.xml 配置解析DBLE rule.xml 配置解析| 案例分析DBLE和Mycat跨分片查询结果不一致案例分析| 社区活动如何获取全国 25场 MySQL 主题大会免费入场券开源分布式中间件DBLE GitHub主页:https://github.com/actiontech…技术交流群:669663113开源数据传输中间件DTLEGitHub主页:https://github.com/actiontech…技术交流群:852990221

February 28, 2019 · 1 min · jiezi

分布式事务中间件 Fescar - 全局写排它锁解读

前言一般,数据库事务的隔离级别会被设置成 读已提交,已满足业务需求,这样对应在Fescar中的分支(本地)事务的隔离级别就是 读已提交,那么Fescar中对于全局事务的隔离级别又是什么呢?如果认真阅读了 分布式事务中间件Txc/Fescar-RM模块源码解读 的同学应该能推断出来:Fescar将全局事务的默认隔离定义成读未提交。对于读未提交隔离级别对业务的影响,想必大家都比较清楚,会读到脏数据,经典的就是银行转账例子,出现数据不一致的问题。而对于Fescar,如果没有采取任何其它技术手段,那会出现很严重的问题,比如:如上图所示,问最终全局事务A对资源R1应该回滚到哪种状态?很明显,如果再根据UndoLog去做回滚,就会发生严重问题:覆盖了全局事务B对资源R1的变更。那Fescar是如何解决这个问题呢?答案就是 Fescar的全局写排它锁解决方案,在全局事务A执行过程中全局事务B会因为获取不到全局锁而处于等待状态。对于Fescar的隔离级别,引用官方的一段话来作说明:全局事务的隔离性是建立在分支事务的本地隔离级别基础之上的。在数据库本地隔离级别 读已提交 或以上的前提下,Fescar 设计了由事务协调器维护的 全局写排他锁,来保证事务间的 写隔离,将全局事务默认定义在 读未提交 的隔离级别上。我们对隔离级别的共识是:绝大部分应用在 读已提交 的隔离级别下工作是没有问题的。而实际上,这当中又有绝大多数的应用场景,实际上工作在 读未提交 的隔离级别下同样没有问题。在极端场景下,应用如果需要达到全局的 读已提交,Fescar 也提供了相应的机制来达到目的。默认,Fescar 是工作在 读未提交 的隔离级别下,保证绝大多数场景的高效性。下面,本文将深入到源码层面对Fescar全局写排它锁实现方案进行解读。Fescar全局写排它锁实现方案在TC(Transaction Coordinator)模块维护,RM(Resource Manager)模块会在需要锁获取全局锁的地方请求TC模块以保证事务间的写隔离,下面就分成两个部分介绍:TC-全局写排它锁实现方案、RM-全局写排它锁使用一、TC—全局写排它锁实现方案首先看一下TC模块与外部交互的入口,下图是TC模块的main函数:上图中看出RpcServer处理通信协议相关逻辑,而对于TC模块真实处理器是DefaultCoordiantor,里面包含了所有TC对外暴露的功能,比如doGlobalBegin(全局事务创建)、doGlobalCommit(全局事务提交)、doGlobalRollback(全局事务回滚)、doBranchReport(分支事务状态上报)、doBranchRegister(分支事务注册)、doLockCheck(全局写排它锁校验)等,其中doBranchRegister、doLockCheck、doGlobalCommit就是全局写排它锁实现方案的入口。/*** 分支事务注册,在注册过程中会获取分支事务的全局锁资源*/@Overrideprotected void doBranchRegister(BranchRegisterRequest request, BranchRegisterResponse response, RpcContext rpcContext) throws TransactionException { response.setTransactionId(request.getTransactionId()); response.setBranchId(core.branchRegister(request.getBranchType(), request.getResourceId(), rpcContext.getClientId(), XID.generateXID(request.getTransactionId()), request.getLockKey()));}/*** 校验全局锁能否被获取到*/@Overrideprotected void doLockCheck(GlobalLockQueryRequest request, GlobalLockQueryResponse response, RpcContext rpcContext) throws TransactionException { response.setLockable(core.lockQuery(request.getBranchType(), request.getResourceId(), XID.generateXID(request.getTransactionId()), request.getLockKey()));}/*** 全局事务提交,会将全局事务下的所有分支事务的锁占用记录释放*/@Overrideprotected void doGlobalCommit(GlobalCommitRequest request, GlobalCommitResponse response, RpcContext rpcContext)throws TransactionException { response.setGlobalStatus(core.commit(XID.generateXID(request.getTransactionId())));}上述代码逻辑最后会被代理到DefualtCore去做执行如上图,不管是获取锁还是校验锁状态逻辑,最终都会被LockManger所接管,而LockManager的逻辑由DefaultLockManagerImpl实现,所有与全局写排它锁的设计都在DefaultLockManagerImpl中维护。首先,就先来看一下全局写排它锁的结构:private static final ConcurrentHashMap<String, ConcurrentHashMap<String, ConcurrentHashMap<Integer, Map<String, Long>>>> LOCK_MAP = new ConcurrentHashMap<~>();整体上,锁结构采用Map进行设计,前半段采用ConcurrentHashMap,后半段采用HashMap,最终其实就是做一个锁占用标记:在某个ResourceId(数据库源ID)上某个Tabel中的某个主键对应的行记录的全局写排它锁被哪个全局事务占用。下面,我们来看一下具体获取锁的源码:如上图注释,整个acquireLock逻辑还是很清晰的,对于分支事务需要的锁资源,要么是一次性全部成功获取,要么全部失败,不存在部分成功部分失败的情况。通过上面的解释,可能会有两个疑问:1. 为什么锁结构前半部分采用ConcurrentHashMap,后半部分采用HashMap?前半部分采用ConcurrentHashMap好理解:为了支持更好的并发处理;疑问的是后半部分为什么不直接采用ConcurrentHashMap,而采用HashMap呢?可能原因是因为后半部分需要去判断当前全局事务有没有占用PK对应的锁资源,是一个复合操作,即使采用ConcurrentHashMap还是避免不了要使用Synchronized加锁进行判断,还不如直接使用更轻量级的HashMap。2. 为什么BranchSession要存储持有的锁资源这个比较简单,在整个锁的结构中未体现分支事务占用了哪些锁记录,这样如果全局事务提交时,分支事务怎么去释放所占用的锁资源呢?所以在BranchSession保存了分支事务占用的锁资源。下图展示校验全局锁资源能否被获取逻辑:下图展示分支事务释放全局锁资源逻辑以上就是TC模块中全局写排它锁的实现原理:在分支事务注册时,RM会将当前分支事务所需要的锁资源一并传递过来,TC获取负责全局锁资源的获取(要么一次性全部成功,要么全部失败,不存在部分成功部分失败);在全局事务提交时,TC模块自动将全局事务下的所有分支事务持有的锁资源进行释放;同时,为减少全局写排它锁获取失败概率,TC模块对外暴露了校验锁资源能否被获取接口,RM模块可以在在适当位置加以校验,以减少分支事务注册时失败概率。二、RM-全局写排它锁使用在RM模块中,主要使用了TC模块全局锁的两个功能,一个是校验全局锁能否被获取,一个是分支事务注册去占用全局锁,全局锁释放跟RM无关,由TC模块在全局事务提交时自动释放。分支事务注册前,都会去做全局锁状态校验逻辑,以保证分支注册不会发生锁冲突。在执行Update、Insert、Delete语句时,都会在sql执行前后生成数据快照以组织成UndoLog,而生成快照的方式基本上都是采用Select…For Update形式,RM尝试校验全局锁能否被获取的逻辑就在执行该语句的执行器中:SelectForUpdateExecutor,具体如下图:基本逻辑如下:执行Select … For update语句,这样本地事务就占用了数据库对应行锁,其它本地事务由于无法抢占本地数据库行锁,进而也不会去抢占全局锁。循环掌握校验全局锁能否被获取,由于全局锁可能会被先于当前的全局事务获取,因此需要等之前的全局事务释放全局锁资源;如果这里校验能获取到全局锁,那么由于步骤1的原因,在当前本地事务结束前,其它本地事务是不会去获取全局锁的,进而保证了在当前本地事务提交前的分支事务注册不会因为全局锁冲突而失败。注:细心的同学可能会发现,对于Update、Delete语句对应的UpdateExecutor、DeleteExecutor中会因获取beforeImage而执行Select..For Update语句,进而会去校验全局锁资源状态,而对于Insert语句对应的InsertExecutor却没有相关全局锁校验逻辑,原因可能是:因为是Insert,那么对应插入行PK是新增的,全局锁资源必定未被占用,进而在本地事务提交前的分支事务注册时对应的全局锁资源肯定是能够获取得到的。接下来我们再来看看分支事务如何提交,对于分支事务中需要占用的全局锁资源如何生成和保存的。首先,在执行SQL完业务SQL后,会根据beforeImage和afterImage生成UndoLog,与此同时,当前本地事务所需要占用的全局锁资源标识也会一同生成,保存在ContentoionProxy的ConnectionContext中,如下图所示。在ContentoionProxy.commit中,分支事务注册时会将ConnectionProxy中的context内保存的需要占用的全局锁标识一同传递给TC进行全局锁的获取。以上,就是RM模块中对全局写排它锁的使用逻辑,因在真正执行获取全局锁资源前会去循环校验全局锁资源状态,保证在实际获取锁资源时不会因为锁冲突而失败,但这样其实坏处也很明显:在锁冲突比较严重时,会增加本地事务数据库锁占用时长,进而给业务接口带来一定的性能损耗。三、总结本文详细介绍了Fescar为在 读未提交 隔离级别下做到 写隔离 而实现的全局写排它锁,包括TC模块内的全局写排它锁的实现原理以及RM模块内如何对全局写排它锁的使用逻辑。在了解源码过程中,笔者也遗留了两个问题:1. 全局写排它锁数据结构保存在内存中,如果服务器重启/宕机了怎么办,即TC模块的高可用方案是什么呢?2. 一个Fescar管理的全局事务和一个非Fescar管理的本地事务之间发生锁冲突怎么办?具体问题如下图,问题是:全局事务A如何回滚?对于问题1有待继续研究;对于问题2目前已有答案,但Fescar目前暂未实现,具体就是全局事务A回滚时会报错,全局事务A内的分支事务A1回滚时会校验afterImage与当前表中对应行数据是否一致,如果一致才允许回滚,不一致则回滚失败并报警通知对应业务方,由业务方自行处理。参考Fescar官方介绍fescar锁设计和隔离级别的理解姊妹篇:分布式事务中间件TXC/Fescar—RM模块源码解读本文作者:中间件小哥阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

February 27, 2019 · 1 min · jiezi

分布式熔断降级平台aegis

现状分布式场景中。若服务不稳定,会导致调用方服务也不可用,从而造成雪崩效应。因此要对在原服务不可用时进行熔断降级处理。分析熔断降级可以服务端限流、网关限流、客户端限流。1. 客户端限流:在调用方法发起请求时检查是否达到阀值。若达到阀值,不发起调用请求优点:可以在服务消费端直接控制流量出口,减少不必要请求的发起。缺点:客户端需要感知服务运行指标和容灾规则。每个业务方需要重复开发2. 服务端限流:服务提供方自定义容灾逻辑,在收到请求后再根据当前状态判断是否走fallback逻辑优点:容灾规则、阀值完全封装在服务提供者。对调用方无感知。缺点:若服务提供者都挂了,无法进行容灾。3. 网关限流:原本直接调用提供者的请求都由网关层代理转发。容灾规则的配置、降级逻辑都封装在网关层。优点:客户端、服务端都无需感知容灾逻辑。缺点:多了一次网络请求、rt变大大部分情况下,我们都是选择服务端限流。但客户端对数据平台的接口是强依赖的。若搜索应用挂了,客户端还是需要看到数据。相比高可用,略微的rt变大是可以接受的,所以启动一个数据容灾网关技术选型现在了解到的开源容灾框架有hystrix、sentinel两种。hystrix:常用于springcloud的一个熔断降级组件。主要功能是不同服务之间的资源隔离、失败降级。底层实现是Rxjava。它提供两种资源隔离的模式:信号量隔离和线程池隔离。一般使用线程池隔离。耗费一定资源,但相比之下支持超时和异步执行。听起来可以覆盖大部分场景,但它不支持更高要求的流控,如qps的控制。所以需要单独采用令牌漏桶来做流量控制。sentinel:阿里开源的分布式流量控制组件。支持流控、熔断降级、系统保护等。所有的资源都对应一个资源名称以及一个Entry。每一个Entry创建的时候,同时也会创建一系列插件(系统保护插件:SystemSlot、流控插件:FlowSlot、熔断降级插件LDegradeSlot等)。每个插件会监控自己职责范围内的指标。NodeSelectorSlot将各个资源的调用路径以树状存储,用于限流降级。调用者通过创建上下文、请求token来执行方法。若没有抛出BlockException,表示请求成功。它支持并发数/qps的流量控制、也支持熔断降级。对比:1.hystrix的熔断都围绕线程池展开。更适合做资源隔离,但单个应用有多个服务时线程池开销会造成浪费。hystrix是单个超时立即熔断,控制力度更细。多个微服务的场景可以考虑用这种。2.sentinel是基于并发数,支持的场景也更复杂,开销小,适合在保证服务稳定的情况下提高吞吐量。但它的超时是5次请求的平均响应时间。并不是很严格。但对于大多数场景而言可以接受接入方式sentinel支持api和注解两种接入方式。作为容灾网关,之后可以会接很多接口。为了接入简单、对代码无侵入。需要使用注解的方式。但是原生的@SentinelResource有几个问题:1. 只能指定资源名称、fallback方法。用户还是需要通过api创建容灾规则,2. 而且fallback方法入参要加上BlockException。这样的接入方式不是很优雅。3. 流控异常FlowException的方法要另外指定。于是基于sentinel封装了一层自定义注解@AegisResource@AegisResource(value = “hello”,limitThread = 0,timeOut = 100,failRate = 0.5,timeWindows = 100,fallback = “exceptionHandler”)参数说明:value:资源名称,默认为方法名limitThread:最大线程数,默认-1,即不启用timeOut:接口超时时间,默认-1,即不启用failRate:失败率,默认-1,即不启用timeWindows:触发降级但持续时间,默认100fallback:降级方法,必须指定接入demo /** * 保护的方法 * @return / @GetMapping(“resourcetest”) @AegisResource(value = “hello”,limitThread = 0,timeOut = 100,failRate = 0.5,timeWindows = 100,fallback = “exceptionHandler”) public String hello() { return “ok”; } /* * 降级的方法 * @return */ public String exceptionHandler() { // Do some log here. return “Oops, error occurred at " ; }新接口只需写好希望执行的方法和降级方法,然后在希望执行的方法上加入@AegisResource(fallBack=“fallback的方法名”)就可以无侵式入地进行容灾。切面定义了默认容灾阀值。也可以在对应属性上设置自定义的阀值。后期规划目前容灾网关可以满足目前的需求。目前有开源的控制台,可以查看服务调用大盘,动态调整容灾规则。缺点是目前指标的搜集是http方式。容灾规则、运行指标也没有持久化存储。后期如果需要,可以借助现有的开源控制台进行二次开发。

February 26, 2019 · 1 min · jiezi

开源分布式中间件 DBLE Server.xml 配置解析

DBLE是基于开源项目MyCat发展的企业级开源分布式中间件,适用于高并发及TB级海量数据处理场景;江湖人送外号 “MyCat Plus”;其简单稳定,持续维护,良好的社区环境和广大的群众基础使DBLE得到了社区的大力支持。DBLE项目介绍DBLE 官方项目: https://github.com/actiontech…如对源码有兴趣或者需要定制的功能的可以通过源码编译安装DBLE 下载地址:https://github.com/actiontech…DBLE 官方社区交流群:669663113DBLE的主要配置文件前两篇文章"DBLE Rule.xml 配置解析"、“DBLE Schema.xml 配置解析” 分别介绍DBLE中Rule.xml和Schema.xml的配置,今天继续介绍DBLE中Server.xml文件的配置,希望通过本篇的介绍,能对Server.xml文件的整体结构和内容有较为清晰的认识,方便大家能快速地入门。DBLE的配置文件都在conf目录里面,常用的几个配置文件如下:DBLE是一个JAVA分库分表中间件,既然是JAVA应用肯定会有JVM相关的配置,在DBLE中我们选择wrapper来作为管理DBLE进程的工具,配置文件在conf/wrapper.conf中,关于JVM的详细介绍在wrapp.conf。Server.xml配置解析Server.xml是DBLE的重要配置文件之一, 整体配置可以分为三段,<system>段,<user>段和<firewall>段,分别定义了DBLE软件的相关配置,用户配置和针对用户的权限控制功能。<dble:server> <system></system> <user></user> <firewall> <whitehost></whitehost> </firewall></dble:server>关于配置文件,如果在DBLE运行途中修改了配置,要想配置动态生效,只需要使用reload @@config命令,但是需要提醒的是reload @@config对Server.mxl中的<system>段中的内容无法生效,即如果修改了server.xml的system的配置,需要重新启动DBLE使其生效 ,更多关于DBLE管理命令请参考DBLE管理端命令同样以思维导图的方式归纳如下,其中个别参数配置只是粗略地将最重要的参数罗列出来,详细的参数还请参考官方文档。system配置DBLE通过Server.xml配置文件来定义相关管理行为,如监听端口,sql统计和控制连接行为等功能,DBLE除了支持分库分表功能外,还实现了类似MySQL的慢查询日志功能,并且支持使用pt-query-digest这样的工具进行慢查询SQL分析,极大地方便了DBA的SQL性能分析与问题SQL定位,以下简单列出了一些最重要的也是最基础的功能配置。用户配置用户配置在<user>段进行配置,因为在Schema.xml中允许多个schema的存在,因此业务用户也是允许多个用户同时存在,并且还可以给这些用户进行更小粒度的权限划分。以实际场景来举例,比如当前配置了两个逻辑库adv和motor,分别是汽车和广告业务,这两个库直接没有任何的关联,因此需要分别配置两个用户来使用这两个schema,一个是adv_user,另一个是motor_user,这两个用户登录上去DBLE能看到只有自己的schema,其他schema不可见,两个用户的配置如下:<user name=“adv_user”> <property name=“password”>adv_user</property> <property name=“schemas”>adv</property> <property name=“readOnly”>false</property> </user> <user name=“motor_user”> <property name=“password”>motor_user</property> <property name=“schemas”>motor</property> <property name=“readOnly”>false</property> </user>但是你可能会想万一这两个库之中的表有关联查询呢?对应场景是:我们需要有个用户叫adv_motor_user,它对motor和adv库都需要有权限访问,别担心,DBLE提供了对单个用户可以访问多个schema的配置方式,我们可以在schemas中指定多个schema,之间用逗号分隔,配置生效后使用这个用户就能登录看到两个schema。<user name=“adv_motor_user”> <property name=“password”>adv_motor_user</property> <property name=“schemas”>motor,adv</property> <!–多个逻辑库之间使用逗号分隔,这些逻辑库必须在Schema.xml中定义–> <property name=“readOnly”>false</property> <!–用来做只读用户–> </user>你可能还会想,这样的权限粒度依然不够细,我们需要更细粒度的权限控制,比如需要adv_user的权限仅限于增删改查权限,即需要将权限细分到dml语句, DBLE仍然提供这样的配置,我们可以继续增加privileges的配置,如下图示:<user name=“adv_user”> <property name=“password”>adv_user</property> <property name=“schemas”>adv</property> <property name=“readOnly”>false</property> <privileges check=“true”> <schema name=“adv” dml=“1110” > <!– 默认库中所有逻辑表的继承权限 –> <table name=“tb01” dml=“1111”></table> <!– 单独指定表权限 –> </schema> </privileges></user>privileges的check参数作用于是否对用户权限进行检查,默认是不检查,dml的权限是分别是INSERT UPDATE SELECT DELETE四种权限,用4个数字0或1的组合来表示是否开启, 1表示开启,0表示关闭。在上图中, adv_user对adv库中所有表的默认权限是'1110’, 即只有insert, update和select权限, 即如果没有像tb01那样详细地列出来的情况,所有表的权限继承权限1110,上面例子中,ta01作为特殊指定的逻辑表的权限,adv_user对该表的权限是1111。我们可以看到DBLE可以将权限划分到DML,并且是可以精确到某一逻辑表级别,对于只需要DML权限的场景是足够了,但是这种权限控制还是很粗略,比如如果想让adv_user除了有dml权限之外,还需要有drop table权限,这时候在用DBLE的privileges权限控制就显得无能为力了,因此可行的建议是:控制连接后端MySQL的用户的权限,将DBLE侧的权限完全放开,换句话说只严格限制schema.xml的writehost中配置的连接用户的权限。 使用后面要讲的黑名单提供的权限控制。黑白名单配置针对上的权限粒度略显粗略的限制(事实上大多数场景下DML的权限也已经足够了),DBLE提供黑白名单的功能,白名单就是只允许白名单的连接,而黑名单则是详细的针对已经通过白名单的连接的权限控制,黑名单更类似于SQL审计, 黑名单配置以firewall分隔开来, 典型配置如下:<firewall> <whitehost> <host host=“127.0.0.1” user=“adv_user”/> <host host=“127.0.0.1” user=“admin”/> </whitehost> <blacklist check=“true”><property name=“selelctAllow”>false</property> <!– 允许select–><property name=“insertAllow”>false</property> <!– 允许insert–><property name=“updateAllow”>false</property>…… </blacklist></firewall>对于黑白名单,需要注意:DBLE针对来源IP和用户名进行限制,放行白名单连接,对于不在白名单列之中的连接,统统拒绝而无法登陆。白名单中的来源ip,只能指定固定IP, 暂不支持MySQL “%‘‘类似的ip通配符。 想象一种场景,需要像MySQL一样指定一个ip范围能允许连接DBLE,这时只能一行一行增加允许ip了,此处略显笨拙。如果配置了黑名单,则再根据黑名单中的权限property来进一步限制白名单中的用户权限,例如是否允许查询,是否允许INSERT,是否允许UPDATE。可以看出DBLE中黑名单更像是对用户的权限审计,DBLE在黑名单中将上面只能粗糙地限制到DML权限的用户配置做了较多较细的扩展,这样权限粒度更小,从实际场景来说,这更符合生产需要,由此我们可以针对性地去掉一些危险的SQL。总结本文简单介绍了Server.xml中的三个重要的配置段落,分别是DBLE的系统配置,用户配置以及黑白名单功能,针对用户配置则介绍了实际应用场景下的配置以及对应的DML权限配置,并详细介绍了DBLE黑白名单配置实践。往期精选| 社区投稿DBLE和Mycat跨分片查询结果不一致案例分析DBLE 自定义拆分算法DBLE rule.xml 配置解析| 使用指南开源分布式中间件 DBLE 快速入门指南DBLE Schema.xml 配置解析| 社区活动如何获取全国 25场 MySQL 主题大会免费入场券 ...

February 20, 2019 · 1 min · jiezi

社区投稿 | DBLE rule.xml 配置解析

文章来源:爱可生云数据库作者:余朝飞DBLE项目介绍DBLE官方网站:https://opensource.actionsky.com可以详细了解DBLE的背景和应用场景,本文不涉及到的细节都可在官方文档获得更细节都信息;对于刚了解到同学,可以以本文为快速入门基础DBLE官方项目:https://github.com/actiontech…如对源码有兴趣或者需要定制的功能的可以通过源码编译DBLE下载地址:https://github.com/actiontech…建议下载最新的releases版本,下载tar压缩包即可,如有源码编译需求的,可以下载源码包DBLE的主要配置文件上一篇"DBLE Schema.xml 配置解析"详细介绍了DBLE之中关于Scema.xml的配置,本篇文章将继续为大家讲解一下DBLE中Rule.xml文件的配置。DBLE的配置文件都在conf目录里面,常用的几个配置文件如下:文件说明server.xmlDBLE server相关参数定义,包括dble性能,定时任务,端口,用户配置等;本文主要涉及到访问用户的配置schema.xmlDBLE具体分片定义,规定table和schema以及dataNode之间的关系,指定每个表格使用哪种类型的分片方法,定义每个dataNode的连接信息等rule.xmlDBLE实际用到的分片算法的配置rule.xml配置解析其中rule.xml是日常配置分片算法的时候最常用到的配置文件,我们通过思维导图的方式给大家整理了DBLE的rule.xml的配置,需要注意的是思维导图不能代替看文档,导图只能起着概括归纳的作用,详细的细节还请参考官方文档。rule.xml举例从分片的数据在各个数据节点分布来看,分片可分为连续分片和离散分片,连续分片就是将一定范围内的数据全部分布在某一DataNode, 离散分布则是通过hash取模等方法将数据打散较为均匀地分布在各个DataNode。分片连续分片离散分片优点并发访问能力有限,扩容迁移代价小并发访问能力增强 范围条件查询性能提升缺点存在数据热点的可能性,并发访问能力受限于单一或少量DataNode .数据扩容比较困难,需要对整体数据做重新分布。举例date,numberrangehash, stringhash, patternrange注:hash,patternrange分片方式如果配置分片区间足够宽的话也是可以当做连续分片的。以下我以PatternRange算法为例,讲解一下如何配置该拆分算法,比如当前有一张表tasK_log已经有1000万的数据,这张表又因为需要和其他表进行关联查询,单表太大进行关联时异常缓慢,因此我们需要对这张表做拆分, 将这张表分别放在三个分片上,dn1,dn2,dn3。schema.xml中的配置如下 <table name=“tasK_log” dataNode=“dn1,dn2,dn3” rule=“three_node_range” />rule.xml中配置如下:<?xml version=“1.0”?><!DOCTYPE dble:rule SYSTEM “rule.dtd”><dble:rule xmlns:dble=“http://dble.cloud/"> <tableRule name=“three_node_range”> <rule> <columns>id</columns> <algorithm>three_node_range</algorithm> </rule> </tableRule> <function name=“three_node_range” class=“PatternRange”> <property name=“mapFile”>partition.txt</property> <property name=“patternValue”>1024</property> <property name=“defaultNode”>0</property> </function></dble:rule>mapfile partition.txt定义如下:[root@localhost ~]# cat partition.txt 0-255=0256-511=1512-1024=2查找路由时,将id字段与patternValue取模,即计算M = id % patternValue,如果M在0-255之间,在数据落在dn1分片。如果M在256-511之间,在数据落在dn2分片。如果M在512-1024之间,则数据落在dn3分片。如果都匹配不上,则落在默认节点defaultNode dn1分片(理论上在这个例子中是不可能匹配不上的)关于每一种拆分算法的详细介绍请参加官方文档介绍。总结rule.xml定义实际用到的拆分算法以及该拆分算法对应到的逻辑库使用使用算法,熟悉各种拆分算法的详细配置及其适用场景,才方便我们在众多数据拆分场景选择并配置合适的拆分规则,同时这也是适用分库分表中间件的第一步,并且实地演示了一个小小的拆分例子,使用到了patternrange算法。将表的详细拆分规则写在配置中,这是一种很"傻"的方式,但是这也是万不得已的一种选择,如果不通过配置文件的方式告诉中间件这些信息,那么中间件就无从得知底层具体的数据分布情况,也就达不到我们最终想要分库分表的目的了。

February 18, 2019 · 1 min · jiezi

一位技术校招生在支付宝的成长笔记

哪有那么多的“逆袭”,唯有努力与坚持,机会就会在前方。鲁直,1989年生,本科毕业于浙江工业大学,之后被校招进阿里巴巴。虽然,今年刚刚30岁,但他已是蚂蚁金服SOFA中间件开源负责人。看到这个开头,是不是觉得我们要向大家讲述一个普通程序员励志“逆袭”的故事?不,并不是这样。前4年,他的人生剧本和别人并没有什么不同但机会总是留给有准备的人“当时就是不想考研究生,而刚好阿里给的offer又能让我在杭州‘活’下去。”鲁直推了推眼镜,淡淡地说。2009年,鲁直报名参加了阿里和浙江工业大学校企合作的实习项目,经过1年的实习期,他在毕业季里成功拿下了B2B团队的offer。最初的时候,鲁直对于业务架构根本谈不上了解,只是每天重复着很普通,甚至是略微枯燥的代码工作。在当时,鲁直的工作就是做产品的研发以及业务系统的开发。每天想着的是建模和现在的业务模型是否匹配,IE6下能不能兼容……和大多数踏出校门、初入职场的大学生没什么不同。鲁直的生活和职业几乎谈不上计划,更谈不上梦想。但是,努力和幸运,让鲁直的人生轨迹逐渐发生变化。“当时的主管对我们说,因为我们刚进公司不久,在技术方面还需要更多的提升。”于是,鲁直就一头扎进开源代码的研究与分析中。在那时,业界的开源意识并不像现在这般普及,但鲁直他们组织的“半民间”开源兴趣小组却坚持了近2年的时间,一帮技术新人相互陪伴着学习开源,看代码,互相指出不足。不断的学习让鲁直对于中间件的兴趣日渐浓厚,他很想在这一领域进行尝试。终于,机会来了!有个同事提议推出一个研发效率提升工具,并被当时的技术主管知道了,他给了鲁直和这个同事一个月的时间把这个工具做出来,而且先不用管业务的事儿。于是,两个人用了一个月的时间,最终拿到结果:一款研发效率提升工具。从看书自学,到组成小团队一起研究代码,再到这次的实操,鲁直在B2B团队3年时间,想清楚了自己究竟要什么。“当时,就认定了自己想要去做中间件”,鲁直说,“而且阿里也有完备的人员流动机制。”于是,鲁直作出了一个重要的决定——从B2B团队转岗到蚂蚁金服中间件SOFA团队。那个属于鲁直的机会终于来了。在SOFA中间件团队5年的挑战与成长学习使人进步如愿以偿,鲁直进入了蚂蚁金服中间件SOFA团队,但这并不意味着是一片坦途。“更忙了,也更充实了;更有趣了,但挑战也更大了。”鲁直略带兴奋地告诉笔者,转岗后,他感受最明显的是角色发生了变化。“之前在业务团队的时候,我只需要具备业务视角即可。但是中间件不一样,需要充分考虑用户的感受。中间件的用户都是研发人员,我需要考量他们的使用场景和习惯等,甚至是在单词拼写以及命名规范等细节。”鲁直说,他必须要较真,因为程序员很多时间都花在变量命名上。随着对中间件的深入,鲁直发现,自己进入了“Hard”模式,之前那些认知看上去都不太管用,甚至有一些可笑。正是基于这种警醒,鲁直知道,不断学习才是自己唯一可选的路。于是,鲁直一头扎进书海,到处找中间件相关的书籍,从最底层的基础理论学起;然后将这些理论知识应用于实际的工作中。为此,鲁直主动要求做很多的支持工作。一段时间之后,鲁直很快就了解了所负责的中间件产品的细节,并快速地积累了解决问题的经验。“这段经历还是蛮有意思的。如果当时只是一味地读死书,而没有将其用于工作中,我想我可能没有那么大的提升。”鲁直感慨到。如果说学习让鲁直感到了愉悦,那么在中间件团队工作期间,收获的“痛苦”又是什么?——“你不知道,项目进度带来的压力真心大。”鲁直说。2016年双11,鲁直所在的SOFA团队负责弹性架构的改造,但其中一个非常老的协议却成了弹性架构下的“bug”。“都知道双11那种紧张的气氛,跟打仗没什么区别。”鲁直说,“架构改造的工作当时因为这个‘bug’而停滞了,整个团队不仅周末连续加班,身体疲惫不已;心理的压力更大。”然而,除了迎难而上,别无它途。鲁直和小伙伴们一起不断对协议进行深入的分析,不断地定制针对性的修复方案,终于让业务顺利升级中间件,平稳地支持了双11。“当时真的是身心俱疲,可以说是非常痛苦了。但最终,我们还是完成了任务。”鲁直说着,镜片后闪过一丝坚定的眼神。在鲁直看来,在越困难的时期,越需要逼自己一把,所谓破釜沉舟,大概如此吧。“SOFA这个名字的来历还挺有意思的,是我们的CTO鲁肃取的名字,里面包含两层意思,一是按照当时的技术趋势,要做面向服务的架构,即Service Oriented Architecture,但加入了金融业务,所以是ServiceOriented Fabric Architecture;二是希望能够像‘沙发’一样,让工程师可以非常爽地工作。”2018年4月,可以让工程师们非常爽的SOFA正式开源了!“现在,SOFA在蚂蚁金服有将近2000个应用,是在蚂蚁业务场景下被不断验证和锤炼的一套框架。”鲁直表示,“把SOFA开源出去,让更多的人使用,对于SOFA未来的发展极具意义。”鲁直告诉笔者,开源的意义就是给技术的发展装上轮子。9年阿里轨迹,一个普通又特别的“码农”越自律越自由程序员的头发,一直是一个不太好玩的老梗。尽管鲁直的头发仍然浓密,但还是能看到在危险边缘疯狂试探的发际线。尽管团队的小伙伴称其为“鲁大师”,但鲁直一直强调自己不过是个平凡的“码农”。“如果哪天,我在阿里的成长完全停滞了,那也就是我离开的时候了。”鲁直悠悠地说到。从大学毕业就在这家公司,9年,是一份执着的坚持。他认为,自己之所以能在阿里巴巴有所成,是因为自己很幸运,在工作中找到了自己的热爱,于是,所有的辛苦都不再是前行的负重,而是助推力。对于中间件的喜欢,以及阿里巴巴和蚂蚁金服提供的阔大舞台,让自己不断面对挑战,不断去学习,不断地成长。鲁直喜欢跑步,即便是天气再冷也会跑个5公里;而且他也喜欢马拉松,陆续坚持了8年之久。在作息时间方面,鲁直也有着“严格”的标准,他要求自己尽量在12点之前睡觉。“熬夜对身体真的不好,而且我跑步也是为了锻炼身体,但这些都其实是我对自己的一些要求。”鲁直说。不管作息规律也好,跑步也好,都可以视作是鲁直对自己的严格自律。鲁直在用自己的行动诠释“越自律越自由”。那些对开源有兴趣的小伙伴们,鲁直给出了自己的建议。“参与开源,一个错别字也是开始。根据对项目了解的深入程度,可以从找错别字、命名规范等找错开始,由浅入深,再去提出Issue、提交Bug。相信所有的开源项目维护者都会非常地欢迎大家一起参与、多提一些意见。”最后,鲁直引用他最喜欢的程序员Jamie Zanwinski的一句话与大家共勉:痛苦造就性格。在舒适的状态下,很多的人表现是差不多的,但是在逆境中,一些人内心非常深处的想法和力量才能被充分发挥出来。SOFA是什么?SOFA(Scalable OpenFinancial Architecture),蚂蚁金服自主研发的金融级分布式中间件,包含了构建金融级云原生架构所需的各个组件,包括微服务研发框架,RPC 框架,服务注册中心,分布式定时任务,限流/熔断框架,分布式链路追踪,分布式高可用消息队列,分布式事务框架等组件。简单来说,SOFA就是包含一整套组件的金融级分布式中间件。诞生于支付宝第2代技术系统的服务化,最开始只有一套框架,后来逐渐形成了一整套完整组件。SOFA和传统金融架构的区别1、传统的金融IT架构一般采取集中式,通过购入大型机小型机解决数据问题,拓展性弱且机器成本高昂。2、SOFA则采取分布式的架构,在高并发交易处理能力、强一致性、秒级容灾和弹性伸缩上都有突出的表现。譬如面对双11流量洪峰时,完全可以准备PC级的服务器去支撑,弹性伸缩。本文作者:越自律越自由阅读原文本文来自云栖社区合作伙伴“阿里技术”,如需转载请联系原作者。

January 25, 2019 · 1 min · jiezi

关于开源分布式事务中间件Fescar,我们总结了开发者关心的13个问题

开源分布式事务中间件 Fescar 自1月10日上线v0.1版本以来,受到了开发者们的极大关注(watch249,star3005,fork649,社区讨论的issue58,数据统计于1月17日14:00),可见,天下苦分布式事务久矣。为此,我们收集了大家在社区(Github)和社群(钉钉群&微信群)关注的核心问题,总结如下,并给出回复。Q1:Fescar 的发展经历了哪些历程?和阿里云全局事务服务GTS之间是什么关系?A1:阿里巴巴是国内最早一批进行应用分布式(微服务化)改造的企业,所以很早就遇到微服务架构下的分布式事务问题。2014 年阿里巴巴中间件团队发布TXC(Taobao Transaction Constructor),为集团内应用提供分布式事务服务。2016 年TXC 经过产品化改造,以GTS(Global TransactionService)的身份上线阿里云,成为当时业界唯一一款云上分布式事务产品,以阿里云公有云或专有云解决方案的形式,交付给众多外部客户。2019 年基于 TXC 和 GTS 的技术积累,阿里巴巴中间件团队发起了开源项目Fescar(Fast & EaSy Commit And Rollback, FESCAR),和社区一起建设这个分布式事务解决方案。TXC/GTS/Fescar一脉相承,为解决微服务架构下的分布式事务问题交出了一份与众不同的答卷。Q2:Fescar 有哪些适用场景?A2:Fescar 的愿景是让分布式事务的使用像现在本地事务的使用一样简单、高效,最终的目标是希望可以适用于所有的分布式事务场景。目前,核心的 AT 模式适用于构建于支持本地 ACID 事务的关系型数据库。非关系型数据库类资源的管理,通过 MT 模式来支持。AT 模式与 MT 模式完全兼容,所以可以在同一个分布式事务中,同时管理两类资源。Q3:目前有已经有一些其他的分布式事务开源方案,Fescar 和他们之间有哪些区别?和JTA支持分布式事务有哪些区别?A3:既有的分布式事务解决方案按照对业务侵入性分为两类,即:对业务无侵入的和对业务有侵入的。业务无侵入的方案既有的主流分布式事务解决方案中,对业务无侵入的只有基于 XA 的方案(注:问题中提到的 JTA 是XA 方案的 Java 版本),但应用XA 方案存在 3 个方面的问题:1、要求数据库提供对 XA 的支持。如果遇到不支持 XA(或支持得不好,比如 MySQL 5.7 以前的版本)的数据库,则不能使用。2、受协议本身的约束,事务资源(数据记录、数据库连接)的锁定周期长。长周期的资源锁定从业务层面来看,往往是不必要的,而因为事务资源的管理器是数据库本身,应用层无法插手。这样形成的局面就是,基于 XA 的应用往往性能会比较差,而且很难优化。3、已经落地的基于 XA 的分布式解决方案,都依托于重量级的应用服务器(Tuxedo/WebLogic/WebSphere 等),这是不适用于微服务架构的。侵入业务的方案实际上,最初分布式事务只有 XA 这个唯一方案。XA 是完备的,但在实践过程中,由于种种原因(包含但不限于上面提到的3 点)往往不得不放弃,转而从业务层面着手来解决分布式事务问题。比如:基于可靠消息的最终一致性方案TCCSaga都属于这一类。这些方案的具体机制在这里不做展开,网上这方面的论述文章非常多。总之,这些方案都要求在应用的业务层面把分布式事务技术约束考虑到设计中,通常每一个服务都需要设计实现正向和反向的幂等接口。这样的设计约束,往往会导致很高的研发和维护成本。不可否认,侵入业务的分布式事务方案都经过大量实践验证,能有效解决问题,在各行种业的业务应用系统中起着重要作用。但回到原点来思考,这些方案的采用实际上都是迫于无奈。回到问题:与基于消息的最终一致、TCC、Saga等业务逻辑侵入方案的不同在于,Fescar 的设计初衷就是保持对业务的非侵入性,不要求业务层面按照分布式事务的特定场景来设计正向和反向的两套(甚至多套)业务逻辑。这方面的差别就不展开了。与 XA 的区别在于,设计了一套不同与 XA 的两阶段协议,在保持对业务不侵入的前提下,保证良好的性能,也避免了对底层数据库协议支持的要求。可以看作是一套轻量级的XA 机制。具体的差别如下:架构层次XA方案的 RM 实际上是在数据库层,RM本质上就是数据库自身(通过提供支持 XA 的驱动程序来供应用使用)。而 Fescar 的RM 是以二方包的形式作为中间件层部署在应用程序这一侧的,不依赖与数据库本身对协议的支持,当然也不需要数据库支持XA 协议。这点对于微服务化的架构来说是非常重要的:应用层不需要为本地事务和分布式事务两类不同场景来适配两套不同的数据库驱动。这个设计,剥离了分布式事务方案对数据库在协议支持上的要求。两阶段提交先来看一下 XA 的2PC 过程。无论 Phase2 的决议是commit 还是 rollback,事务性资源的锁都要保持到Phase2 完成才释放。再看 Fescar 的2PC 过程。分支事务中数据的 本地锁 由本地事务管理,在分支事务 Phase1 结束时释放。同时,随着本地事务结束,连接 也得以释放。分支事务中数据的 全局锁 在事务协调器侧管理,在决议 Phase2 全局提交时,全局锁马上可以释放。只有在决议全局回滚的情况下,全局锁 才被持有至分支的 Phase2 结束。这个设计,极大地减少了分支事务对资源(数据和连接)的锁定时间,给整体并发和吞吐的提升提供了基础。Q4:Fescar 支持 Dubbo 的哪些版本?A4:所有版本。Q5:Fescar 支持 Spring Cloud么?A5:Fescar 与微服务框架的接口点在于,需要把事务的唯一标识 XID(一个字符串)通过微服务框架的服务调用间调用的机制中,透明地传递,并通过 Fescar 的 API 来绑定(或解绑)到应用的线程上下文中。(机制可以参考内置的对 Dubbo 支持的实现 com.alibaba.fescar.dubbo.TransactionPropagationFilter)所以,本质上这个问题不是支不支持 Spring Cloud,而是如何支持 Spring Cloud 中选用的服务调用机制。目前正在和 Spring Cloud Alibaba 的同学合作,准备在v0.5.x版本(或更早)发布对 Spring Cloud默认的支持。同时,非常欢迎社区的朋友参与进来,贡献包括 Spring Cloud 在内的各类微服务框架的支持。Q6:Fescar 是否支持本地跨库多数据源?除了关系型数据库,是否还支持NoSQL数据库?A6:本地跨多数据源同样是支持的,在 Fescar 的架构中,同一个服务中的多个数据源与跨服务的多个数据源,没有本质区别。AT 模式目前仅限于对关系型数据库的支持(本身具备ACID 事务支持),后面会发布出来的 MT 模式可以支持 NoSQL 这类本身不具备本地事务支持的资源。Q7:Fescar 现在开源的是AT模式,MT模式暂时不支持,什么时候会开源?A7:当前 0.1.0 版本只是把 Fescar 最核心的 AT 模式的最小集发布出来,一方面是按开源的规划和架构的重构进展,另一方面也是希望通过最小集版本,让用户和开发者社区更容易理解到我们核心的设计思路,让更多人比较容易地参与进来建设,而不是完全由阿里巴巴主导,仅仅把我们的整套方案开源出来给大家用而已。阿里巴巴在分布式事务上的技术积累,我们会通过 Fescar 项目毫无保留地贡献给社区,所有功能特性都会按规划和社区的反馈陆续开源出来。MT 按初步的计划,会在 0.5.x 版本发布。Q8:Fescar 什么时候提供HA cluster,单节点的server的瓶颈如何处理?A8:按初步的计划,HA Cluster 会在 0.5.x 版本发布,解决单机部署的单点问题。Q9:因网络中断、网张闪断、节点宕机和超时等引起的异常,Fescar会提供相应的补偿措施么?A9:这些异常情况的处理是分布式事务解决方案的基本要求,Fescar 同样也是提供了整套方案来处理各类异常场景。这方面的具体机制会在 HA Cluster 版本发布时,给出全面的分析介绍。Q10:Fescar框架中,如何监控分布式事务?A10:监控是非常重要的一块儿内容。TXC 和 GTS 的监控在阿里巴巴内部使用了很多基础设施的辅助。而在开源版本中,我们还没有一个现成的监控方案。大体上,监控的基础是两个方面:一方面是日志,通过日志的采集和处理,可以形成一个完整的事务链路,这些数据对于业务层面的分析和调优是重要的参考依据。另一方面是 API,Fescar 会提供一套管控 API,用于对运行时事务的管理。我们后续会把这两方面的数据格式、部署形态及接口整理出来,希望和社区来共建监控这个重要的方面。Q11:Fescar 的roadmap 有了么?A11:目前最新的roadmap如下:v0.1.0微服务框架支持: Dubbo数据库支持: MySQL基于 Spring AOP 的 Annotation事务协调器: 单机版本v0.5.x微服务框架支持: Spring CloudMT 模式支持 TCC 模式事务的适配动态配置和服务发现事务协调器: 高可用集群版本v0.8.xMetrics控制台: 监控/部署/升级/扩缩容v1.0.0General Availability: 生产环境适用v1.5.x数据库支持: Oracle/PostgreSQL/OceanBase不依赖 Spring AOP 的 Annotation热点数据的优化处理机制RocketMQ 事务消息纳入全局事务管理NoSQL 纳入全局事务管理的适配机制支持 HBase支持 Redisv2.0.0支持 XA当然,项目迭代演进的过程,我们最重视的是社区的声音,路线图会和社区充分交流及时进行调整。Q12:Fescar 官网什么时候上线?A12:Fescar 官方域名已经注册,官网将采用静态开源站点搭建工具Docsite「传送门」进行搭建,logo 已经设计并将于近期公布。Q13:如何加入 Fescar 社区,进行贡献,已经摩拳擦掌了。A13:我们非常欢迎大家通过各种形式参与到我们项目的建设中,包括但不限于:架构设计模块设计代码实现Bug FixDemo样例文档、网站和翻译具体的参与方法可以参见我们项目中的CONTRIBUTING 指引,或与 @eternaltingting@163.com 联系。实际上,我们并不拘泥于贡献的形式,开发者提出的每一个 issue,无论是Bug Report、改进建议或者甚至是问题咨询都代表着对项目的关注和帮助。希望 Fescar 项目和社区一起健康成长,成为分布式事务领域一个优秀的解决方案。本文作者:中间件小哥阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

January 22, 2019 · 1 min · jiezi

如何基于OceanBase构建应用和数据库的异地多活

摘要: OceanBase是一个通用的分布式的关系型数据库,有很多独特的特点。比如数据库的多租户、高可用、极致弹性伸缩能力。如果把OceanBase当作单库使用,就没有把OceanBase的分布式优势发挥到极致。前言OceanBase是一个通用的分布式的关系型数据库,有很多独特的特点。比如数据库的多租户、高可用、极致弹性伸缩能力。如果把OceanBase当作单库使用,就没有把OceanBase的分布式优势发挥到极致。本文主要分享一个基于分布式架构的应用把OceanBase数据库的分布式优势发挥到极致所需要了解的OceanBase基础,这也是理解蚂蚁金服的基于OceanBase构建的三地五中心异地多活架构的基础。分布式数据库开发相关问题好的性能首先是设计出来的,应用如果追求极致的性能,就需要关注OceanBase里数据的相关事情。如:数据如何分布?数据如何读写?存储容量瓶颈怎么办?访问性能瓶颈怎么办?数据库出故障时数据可用性和可靠性具体怎样?应用需要做什么特殊处理么?数据库扩展时应用需要迁移数据么?数据迁移的时候对应用有什么影响?这些问题对理解OceanBase的分布式特点很有帮助。后面我们逐步看看OceanBase是如何应对。OceanBase集群外观首先简介一下OceanBase集群的外观。OceanBase是以集群形式运行的,由一堆服务器组成。上图是「三副本」部署,机器会分为三组,每组一个区域(称为Zone),各个机器通过网络互相访问。没有光纤交换机、共享存储以及直连网线等。服务器通常建议CPU、内存和磁盘尽可能的大,磁盘建议用普通SSD盘。普通服务器的好处是便宜,劣势是可靠性和性能可能不如小型机那么高。也就是说OceanBase可以部署在一组可靠性和性能不是特别高的普通服务器上,却提供了高性能、高可用和高可靠、弹性伸缩等多项能力。以上是一个OceanBase集群的外观和能力,但是提供给业务的并不是这个集群的全部资源和能力,而是其子集,即租户(Tenant)。OceanBase多租户特性OceanBase定义了一些基本的资源规格(Resource unit config,如4CPU8Gmem500Gdisk等),然后选取某类资源规格创建一组资源池(Resource Pool),此时集群资源就有一部分被分配出去了。最后将这个资源池关联到一个新建租户,则租户就可以使用这个资源池的能力。OceanBase默认有个sys租户,管理整个集群。用户租户必须在sys租户内部创建。如下示例就是创建租户的过程。#sys租户登录方法$mysql -hxxx.xx.11.11 -uroot@sys#obdemo -P2883 -proot oceanbase -A#资源规格(UnitConfig)create resourceunit S0_uc max_cpu=2,max_memory=‘5G’,…资源单元(Unit)create resourcepool Pool_01 unit=‘S0_uc’,unit_num=2,…租户(Tenant)create tenant test_ins resource_pool_list= (‘Pool_01’),…OceanBase兼容了大部分MySQL连接协议和语法,租户的使用体验跟MySQL实例很像。研发可以在租户里创建数据库(Database)、表(Table)。还包括分区表等。OceanBase里描述数据的最小粒度是分区。普通的表(非分区表)就是一个分区,分区表则包含多个分区。租户的示意图如下。租户之间数据是绝对隔离,资源有一定程度隔离。研发可以将业务先垂直拆分为多个独立的子业务,分别使用不同的租户或者集群。OceanBase资源单元租户里并不知道数据具体在哪个机器上,也可以说没必要知道。只是租户的性能还取决于运维为租户规划的资源池分布情况,所以了解一下资源单元的分布特点对性能规划也是有意义的。资源池(Resource Pool)是由一组资源单元(Resource Unit)组成。资源单元数量默认跟Zone的数量一致或者是它的倍数(可以配置具体分布在哪些Zone以及每个Zone里的Unit数量)。如下图资源单元具备一定的资源能力,是数据的容器。租户拥有的资源单元规格和数量决定了这个租户最大性能。资源单元可以在同一个Zone的不同节点之间自由迁移,OceanBase借此来维持各个节点的资源利用率尽可能维持一个均衡状态。OceanBase拆分设计数据库拆分数据库拆分有两种。一是垂直拆分。即按业务模块拆分到不同的实例或库里。为了模块之间互不影响,拆分到不同的实例比较好。在OceanBase里实现时可以是拆分到同一个集群里不同租户或者不同集群里的租户都可以,取决于业务规模和数据库集群规模。垂直拆分很好理解,后面不再赘述。一是水平拆分。即按某个业务维度将数据拆分到多个分片。这些分片可以是在一个库或者不同库或者不同实例的不同库下。水平拆分实现又有两类常用的选择。如下:分库分表。将一个业务表拆分到N个相同结构的物理表中。中间件做业务表(逻辑表)到分表(物理表)的映射路由以及其他相关操作(如结果聚合计算)等。这个N个物理表可以在不同实例的不同分库中。分库的维度和分表的维度可以不一样,比较灵活。分区表。将一个物理表设计为分区表,拆分到N个分区。分区表的各个分区结构是数据库内部保证一致。OceanBase选择的是分区表的水平拆分方式,并且支持二级分区表(即有2个不同的拆分维度叠加使用)。水平拆分示意图如下:上图是分库分表和分区表同时结合使用。业务表order先经过中间件拆分为100个分表(存在10个分库里),每个分表在OceanBase内部又是一个分区表(100个分区)。分库分表的维度和分区表分区的维度都是一致的,根据用户ID。分库分表和分区各有利弊。分库分表的好处是各个分表的结构一致性是在中间件层保证,比较好控制,比较适合灰度变更(允许部分分表结构不一致,最终必须全部一致)。此外更大的好处是,分库分表是实现异地多活单元话架构的必不可少的条件。缺点是中间件的SQL支持范围有限。分区的好处是在数据库内部解决了拆分问题。针对分区表的SQL功能是数据库SQL引擎的本质工作,相关特性(全局索引、二级分区等)会持续开发完善。分区分库分表架构设计,需要确定机器数、实例数、分库数和分表数的拓扑,性能理论上限取决于主实例所处的机器节点数。此后要做扩展就要调整这四个元素的数目及其联系。这种扩展很可能涉及到分表数据的迁移,需要借助外部工具或产品实现。分区架构设计,研发确定分区策略和分区数,运维确定租户的资源单元数量,OceanBase确定资源单元(Unit)在哪些机器节点上以及分区(Partition)在哪些资源单元里。同一个分区不能跨节点存储。如下图。此后要做扩展就是调整资源单元的规格、数量。OceanBase在确定Unit里的分区的位置时会尽量让每个节点的负载维持均衡。这个负载的计算方式比较复杂,会综合考虑OB节点内部CPU、内存和空间利用率等。分区随意分布对应用性能很可能有负面影响。当业务上有联系的两个表的分区分布在不同的资源单元里(同时也分布在不同的节点里),这两个表的连接就难以避免跨节点请求数据,网络上的延时会影响这个连接的性能。注: t1(p0) 表示表t1的0号分区。每个分区在集群里数据实际有三份,即三副本(Replica)。图中忽略了Zone2和Zone3的细节。三副本之间的数据同步靠把Leader副本的事务日志同步到其他Follower副本中。Paxos协议会保障这个事务日志传输的可靠性(事务日志在一半以上成员里落盘,剩余成员最终也会落盘),同时还有个以分区为粒度的选举机制,保障Leader副本不可用的时候,能快速从现有两个Follower副本里选举出新的Leader副本,并且数据还绝对不丢。这里就体现了故障切换时两个重要指标:RPO=0, RTO<30s。Locality图5中t0和t1业务上是有联系的表(如主表和详情表),两者都是分区表,分区策略和分片数都相同,OceanBase提供了一个表属性“表分组”(TableGroup)。设置为同一个表分组的不同表的分区数一定一样,并且同号分区组成一个“分区分组”(PartitionGroup)。同一个分区分组的分区一定会分配在同一个资源单元(Unit)内部(也就是会在同一个节点内部),彼此的连接逻辑就避免了跨节点请求。另外一个效果是如果一个事务同时修改两个有业务关联的分区,使用分区分组也可以规避跨节点的分布式事务。这个表分组属性的设置就是OceanBase的Locality特性之一——影响相关分区的分布。实际上每个分区都有三副本(Replica, 本文例子),图5中省略了t0(p0)和t1(p0)的其他两个副本都分别会在同一个Unit里分配。不仅如此,每个分区的三副本里都会有leader副本默认提供读写服务。leader副本是选举出来的。t0(p0)和t1(p0)的leader副本也一定会在同一个Unit里(即在同一个Zone里)。这样才彻底的避免了连接的时候跨节点请求。OceanBase的Locality特性还可以指定租户/数据库/表的默认Zone,这样下面的表的leader副本会优先被选举为这个Zone里副本。如下面例子,数据库和表会继承租户的默认设置,当然也可以自己修改primary_zone或者locality属性覆盖上层设置。:create tenant obtrans0primary_zone=‘hz1’;create table item (…)locality = ‘F@hz1, F@hz2, F@hz3,R{all_server}@hz1, R{all_server}@hz2, R{all_server}@hz3’注:F表示全功能副本,R表示只读副本。设置primary_zone后单个租户的所有表的读写都集中到一个Zone里,该租户在其他zone里的Unit就没有读写压力。通常这样做是源于业务应用的要求。如应用的请求都是来自于这个Zone,为了规避应用跨Zone读写数据性能下降。不过primary_zone更大的意义在于当集群里有很多租户的时候,可以将不同业务租户的读写压力分摊到不同Zone的机器,这样集群整体资源利用率提升,所有应用的总体性能也得到提升。后面要介绍的异地多活架构就充分利用OceanBase这个特性,在数据库层面将拆分的表的业务读写点尽可能分散到所有Zone的所有机器上。除了表与表之间可能有联系,业务模块之间也可能有联系。一个业务过程可能会横跨多个业务模块,前面这些模块的数据被垂直拆分到多个租户里。OceanBase的Locality特性“租户分组”(TenantGroup)还可以设置不同租户之间的联系。如下租户交易订单和支付订单在业务上是先后发生。create tenantgroup tgtrade tenant_array=(‘obtrade0’, ‘obpay0’);租户分组的意义依然是为了在分布式架构下尽可能将一个业务流程内多次数据库请求都约束在同一个Zone或者Region(注:OceanBase将地域相邻的Zone定义为一个Region)里。OceanBase异地多活架构异地多活概念异地多活的概念一直都有,只是内涵不断变化。以双机房多活为例,应用通常都是无状态的,可以多地部署。数据库有状态,传统数据库只有主库可以提供读写,备库最多只能提供只读服务(如ORACLE的Active Dataguard):1. 应用双活,数据库A地读写,B地不可读写。这种只有应用多活,数据库是异地备份容灾(无并发)。2. 应用双活,数据库A地读写,B地只读。这种也是应用双活,数据库读写分离(实例级并发)。3. 应用双活,数据库双活,两地应用同时读写不同表。这种数据库双向同步,应用同时错开写不同的数据(表级并发)。4. 应用双活,数据库双活,两地应用同时读写相同表不同记录。这种数据库双向同步,应用同时错开写不同的数据(行级并发)。5. 应用双活,数据库双活,两地应用同时读写相同表相同记录。这种数据库双向同步,应用同时写相同的数据,最终会因为冲突一方事务回滚(行级并发写冲突)上面第1种情形,B地应用是跨地域远程读写数据库。两地距离较大的时候性能会很不好。2的B地应用是本地访问数据库。3,4,5三种情形两地数据库都提供读写服务,对应用而言是本地访问数据库,但到分布式数据库内部,其要读写的数据是否正好在本地就取决于业务和数据库的拆分设计。有这么一种情形,B地应用访问B地数据库实例,请求的数据的写入点恰好是A地,这样会走分布式数据库内部路由远程A地实例中拿到数据,性能上会有些下降,而业务可能不知道为什么。OceanBase水平拆分方案为了避免在分布式数据库OceanBase内部发生跨Zone请求,应用的请求流量的水平拆分规则和数据的水平拆分规则要保持一致并联动,就可以实现真正的应用向本地实例请求读写的数据恰好就是在本地实例种。这就是Locality的用途所在。首先业务架构层面能根据用户ID(uid)做拆分,将用户拆分为100分。x和y是用户直接相关的表,都根据uid拆分为100个分表,分布在5个不同的租户里。x[00-19]表示20个分表。每个租户的Leader分别分布在不同的Zone。uid:00-19表示 分到这20个分片的用户数据和用户流量。应用层面在某个环节能根据UID将用户请求转发到对应的机房(Zone),应用服务之间的请求信息都有这个UID信息,后面应用请求都在本机房流转,并且访问数据库时通过分库分表中间件(DBP)和OceanBase的反向代理(OBProxy)就路由到本机房的业务租户上。实际使用这个架构时,有几个隐含的前提,Zone1和Zone2是同城双机房,Zone3和Zone4是同城双机房,两个城市靠的比较近,Zone5 实际很远,所以一般不提供写入。为节省空间,Zone5里的副本放的是日志副本。应用异地多活架构上面要实现OceanBase在每个Zone的应用写入都是恰好是本地访问,关键点就是应用流量水平拆分规则跟数据水平拆分规则保持一致。而应用要维持这样一个规则,需要很多产品都要支持水平拆分等。如下图图中流量接入层的“负载均衡”环节负责调整用户流量到对应的机房(Zone),此后的应用之间的请求就都是本地访问。能使用这个解决方案的业务都是能按用户维度做水平拆分。有些业务的拆分维度跟用户维度是冲突的,或者有些业务的数据只支持集中写入等,不能做到上面这种多活,但也可以使用OceanBase,实现单点写入,多点读取的功能。OceanBase在异地容灾和多活架构方案中的价值就是支持水平拆分规则的定义、解决了多个机房间数据同步和一致性问题、始终具备高可用和弹性伸缩能力等。参考OceanBase负载均衡的魅力蚂蚁金服异地多活的微服务体系本文作者:mq4096阅读原文本文为云栖社区原创内容,未经允许不得转载。

January 9, 2019 · 1 min · jiezi

Dubbo作者亲述:那些辉煌、沉寂与重生的故事

摘要: Dubbo 这个名字,最后会变成一个 Apache 的商标,会成为一个在 GitHub 上有 2 万多人关注、一百多人参与贡献的超级项目。梁飞在 2011 年开源 Dubbo 这个项目的时候,完全没有想过,Dubbo 这个名字,最后会变成一个 Apache 的商标,会成为一个在 GitHub 上有 2 万多人关注、一百多人参与贡献的超级项目。在自己退出这个项目多年后,Dubbo 仍在野蛮生长,并焕发新机。从商业公司开源出去的产品会变成什么样?开源是否一定要按照某种既定的方式去生长?还是说开源的世界有足够的包容性、开放性,能够允许各种各样的创作在其中成长?且看本次二叉树——Dubbo 项目的故事。嘉宾简介梁飞(虚极),2009 年加入阿里巴巴,负责中间件的开发,Dubbo 开源分布式服务框架作者,HTTL 开源模板引擎作者,QCon 优秀出品人。 2012 年加入天猫,负责手机天猫 APP 的技术团队,见证了天猫双 11 无线化全过程。热衷参与开源社区建设,传播服务化,SOA,框架设计,移动应用等架构设计理念。Dubbo 项目诞生于 2008 年。梁飞最早进入阿里的时候,Dubbo 项目还没有 Dubbo 这个名字,那时的 Dubbo 还是一个阿里内部的系统。2010 年,Dubbo 项目进行了重构。“2009 年下半年主要在修 bug,到了 2010 年初的时候觉得这个架构实在是不堪重负,觉得改起来太痛苦了,于是就重写了。”从 1.0 进入 2.0,梁飞推动了大量的工作,同时继续在 JavaEye 写着他的博客。“写博客对你有什么影响?”“在社区里面看别人的博客,他们也在写一些开源软件,大家互相看博客,然后就认识了。推荐我来阿里的朋友就是当时圈子里认识的。”2011 年的阿里,憋了一股劲儿要成为一家技术人向往的企业。那个时候,开发者刚刚成为国内各大厂商争相夺取的宝贵资产。靠什么吸引最顶尖的开发者?黑客文化。工程师文化。开源文化。“那时候公司觉得要做一些开源的事情,一个是反哺开源界,同时也希望通过开源来提升公司的影响力。”当时在淘宝、在阿里 B2B,都有团队在推动开源。阿里 B2B 这边决定先拿 Dubbo 项目开源出去。“大概在 2011 年初做了很多剥离的工作,也把文档做了梳理。我们并没有做很强的推广,我们自己在技术群里发了一些文章,就有人开始在用了。”“那个时候的团队多少人?我看到你们有一张六个人团队的照片。”“人员的变化还是挺多的,六个人是顶峰时期,是我们知名度上来之后加入我们的。我们平时开发基本上就是一到两个为主。”“有外面的人来贡献代码吗?”“有很多人给我们贡献代码。还有很多公司请我们来跟他们讲。”“还有公司问说能不能我们付一点钱,这样的话他们觉得出了问题可以找我们。”“但是我们当时没有这种机制。”一年时间很快过去了,Dubbo 的用户越来越多,有知名汽车厂商、证券厂商、水泥厂商、电器厂商、电商厂商。“当时来这么多公司,在你的预期之内吗?”“超出我的预期。”就在这个时候,发生了一件大事:阿里巴巴集团要强化 One Company,开始进行架构调整。技术层面,整个公司大统一,就希望不要重复建设,但凡相同的项目都要合并。当时的淘宝有一个项目叫做 HSF,也是一个中间件服务框架,跟 Dubbo 做的事情高度重合。“一开始说可以让 HSF 合并到 Dubbo 里面来,给了我们三个月时间要把它们整合起来。”HSF 项目的作者林昊(毕玄),也是当时国内 Java 领域的知名技术领袖。在 OSGi 非常流行的时候,毕玄可能是国内能够把 OSGi 解释的最清楚的人之一。HSF 和 Dubbo,虽然做的事情高度重合,但是设计理念不怎么一样,虽然有些碰撞,但最终目的还是为了“强强联合”。“合并的时候,整个淘系都在用 HSF,而阿里金融、集团、B2B 都在用 Dubbo。”“时间没有达到预期,还是没合并起来。但其实我们把两边的协议都兼容好了。”“后来就决定反向合并,把 Dubbo 合并到 HSF 里面去。”“你当时觉得应该合并吗?”“我觉得协议能互通是有好处的,并不是坏事。我觉得他们做的挺好,把两边的设计理念全部整合在一起了。”不久之后,Dubbo 团队调整,去到了各个地方。从外面看来,Dubbo 项目从 2014 年之后就再也没有更新过。倒是当当网开发的扩展版本 Dubbox 后来持续发展,被圈内人评价为“墙内开花墙外香”。“你会不会觉得建立共识是一个特别困难的事情?”“我觉得任何东西必须要有一个主导,但这个东西其实没有对错。一个设计是没有对错的,有些人可能就是不会认同你这个共识,但你总是能找到认同你共识的人。”“我就是认为越简单越好,我的设计原则就是一定要实用。增加的复杂度越小,能带来更大的收益,我觉得就值得。”“那么,你要怎么吸引那些能够认同你的人到你的身边来?在他们还不知道你的时候。”“我会去其他团队认识人,或者在圈子里面认识人,我会跟他去聊我的理念,我会去分享。有人特别认同的话,他就会来。”就在所有人都以为 Dubbo 项目已经没有未来的时候,事情又出现了变化。2017 年 9 月,就在项目已经将近 3 年没动静的时候,Dubbo 连续发布了好几个新版本,并且开始在内部招募对 Dubbo 感兴趣的同事。新版本背后的主力开发团队是阿里巴巴中间件团队,其中一个重要的人名叫北纬,他从 2017 年 7 月开始接手 Dubbo。在一次对外公开的采访中,北纬说到:“我对 Dubbo 的了解主要来自梁飞在 JavaEye 的系列文章,再通过自己阅读源码,以及在内部 RPC 框架对 Dubbo 兼容的工作中学习所得。”梁飞曾经在 2015 年写过一个继续推动 Dubbo 的规划,找了很多人聊过:找过开源委员会,找过内部的朋友,找过外面的朋友,希望能共同把这个事情继续推起来。但是,梁飞已经没有那么多时间可以投入到 Dubbo 上。他当时在做天猫客户端。“不管是谁,靠一腔热血都很容易凉掉。”有的开源项目,通过志愿者们投入各自的业余时间活下去。但我们应该要求所有的开源项目都能做到这一点吗?事实上,用户也不会愿意将自己重要的东西跑在单纯靠志愿者们的业余时间堆砌起来的项目上——尤其是企业用户。Dubbo 是中间件项目,用户一定是企业。企业用户宁愿花钱,有人给他提供服务,而不是搞来一堆免费而没有保障的东西,自己为所有的问题负责。Dubbo 的转机,在于阿里云的流行。2017 年的阿里云,发现有一批客户上云之后,想要用 Dubbo。因为他们 Dubbo 已经用的很熟了,不想因为上云而被迫改变自己的使用习惯。于是,阿里云就把 Dubbo 服务作为自己的一个产品,卖给了这些客户。但是,客户们又提出了一个问题:“你看你们 Dubbo 都不怎么更新代码了是吧?你们自己都不维护了,我们用你的框架就觉得特别不放心。”这下好了,真正的客户提出要求了。提升客户对 Dubbo 的信心,成为了一件在公司层面有价值的事情。“怎样提升客户对 Dubbo 的信心?”“让它进一步升级。”“最好的办法是什么?”“捐给 Apache。”北纬带动着他的团队,将 Dubbo 项目捐给了 Apache。2018 年初,Dubbo 项目正式进入了 Apache 的孵化器。一边是 Apache Dubbo 重启后的第一个里程碑版本 2.7.0 进入社区投票阶段,并将作为社区的毕业版本;另一边,Dubbo 正在从一个微服务领域的高性能 Java RPC 框架,演进到微服务框架 Dubbo Ecosystem,打造出一个完整的微服务生态。而此时,距离去年 Dubbo 重启仅过一年有余。我们去找到北纬,希望他聊聊 Dubbo 的未来。北纬说,还是让梁飞跟我们多讲讲。“你觉得什么是开源的精神?”“开源的精神,就是大家的智慧能共同成长。”“你觉得中国的开源现在有哪些做得好的地方和不足的地方?”“我觉得中国的开源最缺对社区的重视,很多都只是把代码 push 出来,有些甚至连文档都不完善,好像人家爱用不用,出了问题也不是我的事。但这可能是一个初级阶段,慢慢会成熟起来。但我觉得好的地方就是,大家都相信开源的力量。”“您会不会觉得中国企业做开源,功利心特别重,光去看这个东西是不是有用?”“输出技术影响力是吧?我觉得一个开源社区要能够一直运作下去,而且能跟上时代的潮流,其实是要与时俱进的。我觉得做开源,就是期望这个东西一直有生命力,这个作品能够活多久应该作为它的核心目标。”“那您觉得 Dubbo 还能活多久?”“我觉得技术的革新其实挺快的,不革新的话,就有淘汰的危险。但是在这个节点上进行一次革新的话,我觉得它还有很长的生命力。”“那是什么样的革新?”“任何技术一定是没有终点的。没有任何架构能解决现实中所有的问题,而任何一个架构去解决前面的问题的时候,一定会带来副作用,然后就需要下一个架构去治理。这个探索的方向是没有止境的,但只有你到达了一个阶段,你才能够去想下一个阶段的很多事情。”“回到原点,十年前的选择一定是最正确的吗?就算当时是最正确的,现在也不一定正确对吧?因为时代在变化。如果我们今天从零开始,我们有没有更好的选择?有时候我们背了十年的包袱,反而不敢行动了。但我希望我们下一代演化的时候,我们能够提出一些颠覆式的理念,真正革新的解决我们现在面临的问题背后的那些问题,而不是头痛医头脚痛医脚。这是我们期望做的事情。”如常,早上 9 点多,梁飞打开邮箱,关于 Apache Dubbo 重启后的第一个里程碑版本 2.7.0 的讨论邮件还在 mailing list 里热烈进行着;另一边,Dubbo 正在从一个微服务领域的高性能 Java RPC 框架,演进到微服务框架 Dubbo Ecosystem,打造出完整微服务生态。而此时,距离去年 Dubbo 重启仅过一年有余。本文作者:二叉树阅读原文本文来自云栖社区合作伙伴“InfoQ”,如需转载请联系原作者。 ...

January 3, 2019 · 1 min · jiezi

如何去设计前端框架能力?星巴克消息开放项目从0到1,从点到面的思考

本文由淘宝前端工程师罗嗣分享,主要讲述了作者在星巴克消息开放项目中的总结和思考,希望对大家有帮助,让业务分享更加有价值。摘要从满足星巴克项目需求单点出发,发散到从点到面的思考。从而总结了自己思考的基本流程(方法论)。从如下四个递进方面思考。业务拓展:拓展自有业务的边界,和其他业务合作共建,形成标准的能力透出, 合力共建。业务趋势:业务的特点和趋势是如何。技术可以如何储备来应对未来业务的变化。技术趋势:技术命题,技术趋势。选择适合的技术来解决现在的问题。保持技术对未来的弹性。需求问题:客观存在的事实,现在需求存在哪些问题,我们如何去帮助业务更加稳定,更加高效。本文提纲笔者从0到1构建一个IM前端系统,再从点到面思考整合突破原有的自有业务限制,尽量设计出的可扩展,可交互,甚至小而美的系统能力。本文会从如下几个方面去介绍。点:项目背景及需求难点(支付宝星巴克小程序入驻客服接待),以及现有的能力。面:需求做完反向思考,当前BC/CC遇到的问题及痛点,如何在同一个领域模型下做推动标准化能力。需求介绍项目背景客服接待能力由手淘消息平台和CCO团队合作共建,整体采用AMP+XSPACE的方案落地,AMP承接C端用户聊天界面,XSPACE承接B端聊天界面,同时接待又需要原有BC的聊天能力。星巴克客服接待两纵一横,底部需要对接不同的服务端,上层需要保证同一套UI来提升一致性体验。设计思路总体设计思想:设计分离出数据层和UI层,数据层和UI层以标准化协议对接。这样分层就可以解决当前业务遇到的问题,如下是当时需求的标准SDK事例点到面的思考星巴克客服消息接待开放是一种轻量级(H5形式)的客服接入能力。思考当前业务的问题是什么,如何改进,业务价值的意义等。 笔者会从如下几个方面去思考。原有H5旺旺由于历史原因有稳定性和体验的问题,这套方案能不能提供替换成原来的H5旺旺,同时对聊天接入统一收口(标准化组件)。从而达到更加稳定,更加的体验性。H5旺旺聊天可以投放到阿里系的其他端上(优酷,饿了嘛,拍卖等),甚至现在很多外投的广告业务。把H5聊天能力做强对淘宝的引流及成交都有很大的意义。同时集团里面还有小蜜作为客服聊天能力。能不能站在前端的角度思考整合输出。针对集团二方业务。需要定制个性化消息和UI能力,需要把SDK能力提供给他们去进行上层业务扩展,为保证他们低成本的接入需要提供基础能力,二方去扩展插件。同时工具链路上需要保证提高效率。生成闭环的开发环境,接入业务方只要关系自己的业务需求思考模型基于之前的背景和诉求,整体设计思路: 抽离UI层和数据层(模块),UI层和数据层基于Message实体进行标准化协议对接(桥梁)。工具链路垂直支持提高效能。 有如下几个方面衔接点:开放 UI组件 和 标准化SDK能力,让二方业务快速搭建,UI层 和 数据层之间用 标准化协议做桥梁连接在基础SDK上,会透出Context上下文(内部核心对象message,session,app)让业务去定制修改,业务方只需要去扩展插件。基于DEF脚手架体系提供相应工具链路支持,包括项目模板生成,项目测试,项目构建,完善可持续集成。业务价值在阿里做每件事情,需要明确这件事情的价值,这件事情投入产出比是多少。上文也陆续在提价值。 如图可以说明这件事价值实践方案上面几章介绍了项目背景,设计思路,思考模型和业务价值(PS:类似于论文前两章在介绍背景和理论知识)。这章主要是讲的项目实践。站在前端的角度,从四个方面去实践,并付相应代码地址。标准化协议: 由于消息领域模型是一致的,可以抽象出标准的 会话和 消息 格式。他是SDK和组件能力的桥梁SDK能力开放:提供标准化数据对接的能力,负责插件扩展能力。 业务入驻只需要开发业务相应的中间件(插件)。例如:各自业务的编解码模块,登录模块,消息处理模块组件能力开放:提供标准化的聊天能力组件。例如聊天入口接入标准化组件工具链路支撑:基于DEF脚手架体系,开发了def-kit-tbms套件。支撑项目全链路开发领域模型(标准化协议)为了达到消息标准化能力,需要把基本概念和接口达成一致。梳理两个基础概念: 会话 和 消息。会话conversation: 它是指AB通讯之间维持的一种关系,它是消息存储的载体消息message: 消息是一个对话的基本组成部分, 根据业务分为两大块消息,会话内消息和系统通知消息。会话内消息又可以分为基本消息和自定义消息。会话类型即时通讯 SDK 的核心概念「会话」,即 Conversation。我们将单聊和群聊(包括聊天室)的消息发送和接收都依托于 Conversation 这个统一的概念进行操作。会话属性备注id会话IDscene场景to聊天对象,账号或者群IDupdateTime会话更新时间unread未读数lastMsg此会话的最后一条消息custom扩展Json字符串消息类型IM SDK内的消息可以分为两类:会话内消息和系统通知消息。会话内消息只能出现并展示在聊天界面里,一般是应用内的一个用户发给另一个用户(或群组/聊天室)的消息,例如文本消息、图片消息都属于会话内消息。:会话内消息类型备注文本消息消息内容为普通文本图片消息消息内容为图片URL地址、尺寸、图片大小等信息语音消息消息内容为语音URL地址、时长、大小、格式等信息视频消息消息内容为视频文件的URL地址、时长、大小、格式等信息文件消息消息内容为文件的URL地址、大小、格式等信息,格式不限地理位置消息消息内容为地理位置标题、经度、纬度信息通知消息自定义消息可以用于消息接入扩展。 例如卡片消息,红包消息等。自定义消息**通知消息属于会话内的一种消息,用于会话内通知和提示场景。例如:群名称更新、某某某退出了群聊等。**会话和消息标准化格式标准化协议标准化会话格式标准化消息格式SDK能力开放SDK的设计参考了Koajs的设计原理(底层微创新了下)。Koajs的中间件思路: 中间件对于一次请求来处理,context分别集成了request和response对象, 同理可以映射成对一条收发消息的处理,面向切面的编程方式。。 在context中会集成message(消息),session(会话),app(如用户,初始化sdk信息等其他信息)。整个项目通过lerna进行了包管理,用Typescript写了SDK,并做了充分的单元测试,大家可以放心使用。整个项目分为了如下几个模块:@ali/tbms-compose: 函数组合模块,用于@ali/tbms-middlware服务@ali/tbms-middleware: 中间件模块@ali/tbms-util: 通用函数分装:如promise同步执行队列,mtop请求,event事件系统@ali/tbms-sdk: 消息标准化基础SDK,可以让业务扩展,补充插件测试说明:对底层支持的SDK都做了充分的单元测试,保证稳定性。后续版本更新提供差异性修改的检查使用事例组件能力开放由于需要多端投放,某些二方应用支持weex能力。从而选择了RAX技术方案。再在H5表现下对单聊做性能优化,现阶段完成聊天入口的统一接入组件,上层的组件在陆续完善中(完成度20%)。@ali/rax-tbms-chatwater tbms-components工具链路支撑基于DEF脚手架体系,开发了def-kit-tbms套件。提供项目全链路开发支撑。这个项目后续的项目搭建都采用standard-dev脚手架生成项目目录。例如:tbms-toolkit,tbms-packages总结这是一次完整的一个项目从0到1,从点到面的思考过程,建立模型到付诸于实践。从完成业务需求(需求做什么)到帮助业务成长(我能做什么)的思考过程。虽然只是站在前端角度在思考问题,但是方法论相信可以通用。后续Action改善原来的H5旺旺,使之更加稳定和更好的体验性。同时对聊天接入统一收口(标准化组件和标准化接入SDK)。Flag:利用业余时间,一月中旬前第一版本里程碑发布未完待续有什么IM相关的需求都可以联系我@罗嗣,共建标准化和生态。本文作者:罗嗣阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 19, 2018 · 1 min · jiezi

10分钟读懂阿里巴巴高级专家在Flutter Live2018的分享

12月4日,google flutter团队宣布第一个flutter正式版本发布。次日,Flutter Live Beijing 会议上,google flutter团队邀请了在这一技术方案中重要的合作伙伴闲鱼团队分享这半年以来的通过flutter产出的业务结果以及对应的技术挑战。本文根据Flutter Live Beijing嘉宾闲鱼客户端团队负责人于佳(宗心)的演讲内容进行整理,从flutter的优势和挑战引出闲鱼这半年来针对flutter基础设施进行重新的构建,定义,以及优化的过程,最后是这半年来对社区的一些贡献和未来的规划。Flutter的优势与挑战众所周知,Flutter提供了一套解决方案,既能用原生ARM代码直接调用的方式来加速图形渲染和UI绘制,又能同时运行在两大主流移动操作系统上,其像素级别的还原,保证了不同平台的UI强一致性。同时其提供了一整套机制(hot reload/attach Debug)保证开发的高效,基于此闲鱼团队在众多跨平台方案中选择了Flutter作为其未来主要的开发方案。从4月份开始尝试在业务侧接入flutter到现在,闲鱼在线上已经有10+的页面使用了flutter进行开发,其中覆盖了核心主链路发布和详情。闲鱼目前是市场上最大的闲置交易社区,作为一款有巨大用户体量的C端创新类产品,我们对体验以及研发迭代效率都有比较高的要求。在享受flutter带来的收益的过程中,同样会面临技术转型过程中的一些挑战。主要的挑战来源于以下的三个方面工程体系在现有工程体系下如何将flutter体系融入,并保持团队不同技术栈(Android/iOS/Flutter)的同学能各自独立高效进行开发。业务架构如何提供一套flutter之上的业务架构,保证上层代码的统一标准,同时尽可能的使得代码的复用度及隔离性更好。基础中间件如何保证不同技术栈背后使用的基础能力是一致的(底层统一使用具有相同优化策略的图片库/音视频库),且在这个过程中如何解决flutter融入后产生的问题。面对这些挑战,闲鱼团队在下半年开始了针对基础设施的改造与重建。基础设施重建之路工程体系工程体系部分,首当其冲需要考虑的是不同技术栈同学的协同问题,举例说明,我们的详情和发布页面是flutter的,而首页以及搜索部分目前暂时采用native进行开发。这就需要考虑到flutter的环境要对开发native的同学透明,甚至在native同学没有安装flutter环境的情况下,依然可以保持原来的方式进行开发native页面。如图中所示,以iOS为例,我们针对flutter的框架flutter.framewrok和业务代码App.framework通过持续集成服务进行打包并自动上传至云端的pod repo上,native同学只需在Podfile内指定对应的两个库的版本即可,同理,针对flutter的plugin代码,同样打包上传至pod repo即可。这套体系整体不复杂,需要说明的是,由于多人开发flutter工程,因此打包是一件非常频繁的事情,因此我们这半年构建了持续集成体系来帮助大家将打包上传等整个体系做成一键式服务,另外,由于原有iOS平台的flutter产物是需要依赖我们的native主工程的代码的,这种默认的打包方式,代码量巨大,造成持续集成时间在10-20分钟不等,因此在这个过程中,闲鱼团队通过直接基于xcode_backend.sh + insert_dylib的自定义脚本完成了不依赖native主工程源码的打包,将持续集成时间降至2分半。同理在android上面,也进行了一些基础的改造,感兴趣的同学可以给我们留言,我们会根据大家的需求程度在后续安排贡献给flutter社区。另外一部分比较重要的内容是混合栈相关的,由于flutter没有提供flutter到混合工程的最佳实践,所以我们在上半年自建了一整套混合栈的体系,这里主要是分享一些混合栈的关键思考,在混合栈的实现过程中,需重点测试验证dart这一侧widget的生命周期,并简化堆栈的管理(目前闲鱼的做法是将堆栈管理统一交由native进行控制,简化Dart层API),并需要考虑如何兼容Dart上层的比如Navigtor API的调用。整体这部分闲鱼团队还在验证当中,总之,这部分看似简单,但实际是比较深的坑,需要重点优化。另外,截至发文时间前,我们跟google flutter团队就混合栈交换了一些看法,flutter团队后续如果可以提供多flutterview,单flutter engine的基础能力,就可以使得闲鱼现有的混合栈实现成本整体大幅度降低,后续大家有什么特别好的建议,也欢迎跟我们进行交流。业务架构今年下半年由于有更多的业务迁移至flutter,这意味着更多的团队成员开始了Dart侧的研发。很快我们发现团队的代码风格,层次结构都比较混乱,bug也层出不穷,因此我们需要找到一种可以保证大家研发规范,同时确保多人协同过程中,代码既能更好的复用,又可以在适当的场景下做到相互隔离的这么一种方案。在经过社区的多个框架库的实践和比较以后,不管是flex还是redux都不能完全解决我们的问题。最后我们选择了自己进行设计和实现,我们对框架进行基础分层以后,将重点最终落在了基于单一数据源的组件化框架上面,因此我们产生了自己的框架fishRedux,我们严格参考标准js的redux规范和源码(redux的设计三原则)进行了完整的dart侧的实现,并在此基础上提供扩展能力用于我们的组件化开发。如图所示,component将redux中的view,reducer,middleware以及我们的扩展能力effect进行组装,从而可以在不同的页面进行组件的复用,当然,全局依然遵循redux的单一数据源的原则,但我们将逻辑本身通过更细粒度的拆解,保证了这些逻辑在不同的component组装下都可以尽可能的进行复用。基于这种结构,我们可以将任意的component进行挂载和拼装,通过更多小粒度的组件,产生不同场景下的复杂页面。另外,针对于component的多层组装,大家可以细看下dependents这个字段,通过基于这个字段的组装,在我们提供的这段代码里面,实际上是提供了一个详情页面的插槽的功能,详情页面目前在闲鱼有近10种不同的组合,在这个场景下,可以在保证组件可以服用的同时,做到不同流程下的代码隔离。我们只要针对dependents的components里面进行替换,就可以很容易的达到在详情页面插入不同widget以及逻辑的效果。fishRedux框架目前已经接近修改的尾声,目前还有部分微调和文档的补充,明年4月份前,我们有计划进行该框架的开源,为后续业务架构提供一个新的标准,大家敬请期待。基础中间件在阿里集团内部,已经产出了较多的基础中间件,因此如何复用这个中间件到flutter侧是一个新的挑战,针对于传统的比如网络库,crash收集等中间件,由于不涉及到UI的复用,相对容易,但针对音视频,图片库等这类的中间件,虽然flutter提供了flutterTexture的方案,但依然不是特别完美。我们在做音视频及图片库的复用过程中,主要的问题在于flutter原生提供的机制,针对图片的渲染存在GPU到CPU,然后CPU再到GPU的这样一个过程,如图所示。根本原因在于不同的glContext无法共享texture。因此,我们目前采取的方案是修改flutter引擎,并暴露出glContext的shareGroup(以iOS为例)。目前整个方案已经上线。由于该改动目前在闲鱼自己fork的engine里面,因此目前将我们之前踩到的一些坑同步给大家,如果大家有在flutter和native侧同时使用音视频的情况,建议特别注意ppt中的前两点,否则会造成flutter侧或者native侧音视频的错乱。当然如果按照闲鱼团队的提供的修改方案进行engine改造后,也可以通过第三点,对native设置跟flutter相同的sharegroup来解决这个问题。在flutter live Beijing结束之后,我也将该方案正式介绍给google flutter团队,希望后续能将类似的功能融入flutter的官方实现。闲鱼与flutter社区闲鱼这半年,对于flutter社区,也有一些小小的贡献。我们针对flutter的方案进行整理并在各个技术社区进行传播。另外我们将已有的一些问题和解决方案提供给google flutter官方团队,直接或者间接的推动了flutter的整体进度,并改变了这个技术未来的部分走向。我为自己的团队感到由衷的骄傲,但同时我意识到,要想让flutter成为终端未来的主流技术,依然任重道远,因此我们后续也会将目前的一些相对稳定的框架和解决方案,逐步开源到社区,我们的要求是,至少闲鱼团队需要在线上有应用和验证。目前我们已经有一些初步的demo和小工具放在上面,大家感兴趣的可以往我们的github上提issue,我们后续会逐步开放更多的代码。最近会公布的比较重要的框架会是fishRedux,因此请大家持续关注我们。总结与展望我们首先带大家回顾了flutter带来的优势以及在闲鱼的实际例子,并引出在复杂工程下的一些挑战。我们针对这些挑战,在下半年进行了整个体系的重新建设,初步完成了隔离的混合工程体系统一标准的业务架构高效复用基础中间件设施本次的分享,其实只是我们目前团队的一部分内容,我们基于flutter和dart还有更多的技术方案目前在预研和研发中,所以没有在这次live中进行宣讲。在后续跟google flutter团队的沟通中也了解到,他们对我们的多个方案都有较大的兴趣。对于未来来说,一方面,除了本文分享的内容以外,我们自己在代码自动生成/Dart Server/线上问题自动回放/国际化/动态模版等/持续集成等多个方面都在持续关注和调研。另一方面,在flutter 1.0公布后,类似hummingbrid这一类全新的方案也有机会让flutter具有全终端制霸的可能性,我们也会持续跟进和进行尝试。Anyway,依然希望有更多的同学可以加入我们一起完善flutter的生态,同时通过新的技术手段,让天下没有闲置。来闲鱼一起改变世界吧,少年!PPT下载:https://yq.aliyun.com/download/3130本文作者:闲鱼技术-宗心.阅读原文本文为云栖社区原创内容,未经允许不得转载。

December 11, 2018 · 1 min · jiezi

如何在优雅地Spring 中实现消息的发送和消费

本文将对rocktmq-spring-boot的设计实现做一个简单的介绍,读者可以通过本文了解将RocketMQ Client端集成为spring-boot-starter框架的开发细节,然后通过一个简单的示例来一步一步的讲解如何使用这个spring-boot-starter工具包来配置,发送和消费RocketMQ消息。通过本文,您将了解到:Spring的消息框架介绍rocketmq-spring-boot具体实现使用示例前言上世纪90年代末,随着Java EE(Enterprise Edition)的出现,特别是Enterprise Java Beans的使用需要复杂的描述符配置和死板复杂的代码实现,增加了广大开发者的学习曲线和开发成本,由此基于简单的XML配置和普通Java对象(Plain Old Java Objects)的Spring技术应运而生,依赖注入(Dependency Injection), 控制反转(Inversion of Control)和面向切面编程(AOP)的技术更加敏捷地解决了传统Java企业及版本的不足。随着Spring的持续演进,基于注解(Annotation)的配置逐渐取代了XML文件配置, 2014年4月1日,Spring Boot 1.0.0正式发布,它基于“约定大于配置”(Convention over configuration)这一理念来快速地开发、测试、运行和部署Spring应用,并能通过简单地与各种启动器(如 spring-boot-web-starter)结合,让应用直接以命令行的方式运行,不需再部署到独立容器中。这种简便直接快速构建和开发应用的过程,可以使用约定的配置并且简化部署,受到越来越多的开发者的欢迎。Apache RocketMQ是业界知名的分布式消息和流处理中间件,简单地理解,它由Broker服务器和客户端两部分组成:其中客户端一个是消息发布者客户端(Producer),它负责向Broker服务器发送消息;另外一个是消息的消费者客户端(Consumer),多个消费者可以组成一个消费组,来订阅和拉取消费Broker服务器上存储的消息。为了利用Spring Boot的快速开发和让用户能够更灵活地使用RocketMQ消息客户端,Apache RocketMQ社区推出了spring-boot-starter实现。随着分布式事务消息功能在RocketMQ 4.3.0版本的发布,近期升级了相关的spring-boot代码,通过注解方式支持分布式事务的回查和事务消息的发送。本文将对当前的设计实现做一个简单的介绍,读者可以通过本文了解将RocketMQ Client端集成为spring-boot-starter框架的开发细节,然后通过一个简单的示例来一步一步的讲解如何使用这个spring-boot-starter工具包来配置,发送和消费RocketMQ消息。Spring 中的消息框架顺便在这里讨论一下在Spring中关于消息的两个主要的框架,即Spring Messaging和Spring Cloud Stream。它们都能够与Spring Boot整合并提供了一些参考的实现。和所有的实现框架一样,消息框架的目的是实现轻量级的消息驱动的微服务,可以有效地简化开发人员对消息中间件的使用复杂度,让系统开发人员可以有更多的精力关注于核心业务逻辑的处理。2.1 Spring MessagingSpring Messaging是Spring Framework 4中添加的模块,是Spring与消息系统集成的一个扩展性的支持。它实现了从基于JmsTemplate的简单的使用JMS接口到异步接收消息的一整套完整的基础架构,Spring AMQP提供了该协议所要求的类似的功能集。 在与Spring Boot的集成后,它拥有了自动配置能力,能够在测试和运行时与相应的消息传递系统进行集成。单纯对于客户端而言,Spring Messaging提供了一套抽象的API或者说是约定的标准,对消息发送端和消息接收端的模式进行规定,不同的消息中间件提供商可以在这个模式下提供自己的Spring实现:在消息发送端需要实现的是一个XXXTemplate形式的Java Bean,结合Spring Boot的自动化配置选项提供多个不同的发送消息方法;在消息的消费端是一个XXXMessageListener接口(实现方式通常会使用一个注解来声明一个消息驱动的POJO),提供回调方法来监听和消费消息,这个接口同样可以使用Spring Boot的自动化选项和一些定制化的属性。如果有兴趣深入的了解Spring Messaging及针对不同的消息产品的使用,推荐阅读这个文件。参考Spring Messaging的既有实现,RocketMQ的spring-boot-starter中遵循了相关的设计模式并结合RocketMQ自身的功能特点提供了相应的API(如,顺序,异步和事务半消息等)。2.2 Spring Cloud StreamSpring Cloud Stream结合了Spring Integration的注解和功能,它的应用模型如下:Spring Cloud Stream框架中提供一个独立的应用内核,它通过输入(@Input)和输出(@Output)通道与外部世界进行通信,消息源端(Source)通过输入通道发送消息,消费目标端(Sink)通过监听输出通道来获取消费的消息。这些通道通过专用的Binder实现与外部代理连接。开发人员的代码只需要针对应用内核提供的固定的接口和注解方式进行编程,而不需要关心运行时具体的Binder绑定的消息中间件。在运行时,Spring Cloud Stream能够自动探测并使用在classpath下找到的Binder。这样开发人员可以轻松地在相同的代码中使用不同类型的中间件:仅仅需要在构建时包含进不同的Binder。在更加复杂的使用场景中,也可以在应用中打包多个Binder并让它自己选择Binder,甚至在运行时为不同的通道使用不同的Binder。Binder抽象使得Spring Cloud Stream应用可以灵活的连接到中间件,加之Spring Cloud Stream使用利用了Spring Boot的灵活配置配置能力,这样的配置可以通过外部配置的属性和Spring Boo支持的任何形式来提供(包括应用启动参数、环境变量和application.yml或者application.properties文件),部署人员可以在运行时动态选择通道连接destination(例如,Kafka的topic或者RabbitMQ的exchange)。Binder SPI的方式来让消息中间件产品使用可扩展的API来编写相应的Binder,并集成到Spring Cloud Steam环境,目前RocketMQ还没有提供相关的Binder,我们计划在下一步将完善这一功能,也希望社区里有这方面经验的同学积极尝试,贡献PR或建议。spring-boot-starter的实现在开始的时候我们已经知道,spring boot starter构造的启动器对于使用者是非常方便的,使用者只要在pom.xml引入starter的依赖定义,相应的编译,运行和部署功能就全部自动引入。因此常用的开源组件都会为Spring的用户提供一个spring-boot-starter封装给开发者,让开发者非常方便集成和使用,这里我们详细的介绍一下RocketMQ(客户端)的starter实现过程。3.1. spring-boot-starter的实现步骤对于一个spring-boot-starter实现需要包含如下几个部分:在pom.xml的定义定义最终要生成的starter组件信息<groupId>org.apache.rocketmq</groupId><artifactId>spring-boot-starter-rocketmq</artifactId><version>1.0.0-SNAPSHOT</version>定义依赖包,它分为两个部分: A、Spring自身的依赖包; B、RocketMQ的依赖包<dependencies> <!– spring-boot-start internal depdencies –> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!– rocketmq dependencies –> <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>${rocketmq-version}</version> </dependency></dependencies> <dependencyManagement> <dependencies> <!– spring-boot-start parent depdency definition –> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>${spring.boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies></dependencyManagement>配置文件类定义应用属性配置文件类RocketMQProperties,这个Bean定义一组默认的属性值。用户在使用最终的starter时,可以根据这个类定义的属性来修改取值,当然不是直接修改这个类的配置,而是spring-boot应用中对应的配置文件:src/main/resources/application.properties.定义自动加载类定义 src/resources/META-INF/spring.factories文件中的自动加载类, 其目的是让spring boot更具文中中所指定的自动化配置类来自动初始化相关的Bean,Component或Service,它的内容如下:org.springframework.boot.autoconfigure.EnableAutoConfiguration=\org.apache.rocketmq.spring.starter.RocketMQAutoConfiguration在RocketMQAutoConfiguration类的具体实现中,定义开放给用户直接使用的Bean对象. 包括:RocketMQProperties 加载应用属性配置文件的处理类;RocketMQTemplate 发送端用户发送消息的发送模板类;ListenerContainerConfiguration 容器Bean负责发现和注册消费端消费实现接口类,这个类要求:由@RocketMQMessageListener注解标注;实现RocketMQListener泛化接口。最后具体的RocketMQ相关的封装在发送端(producer)和消费端(consumer)客户端分别进行封装,在当前的实现版本提供了对Spring Messaging接口的兼容方式。3.2. 消息发送端实现普通发送端发送端的代码封装在RocketMQTemplate POJO中,下图是发送端的相关代码的调用关系图:为了与Spring Messaging的发送模板兼容,在RocketMQTemplate集成了AbstractMessageSendingTemplate抽象类,来支持相关的消息转换和发送方法,这些方法最终会代理给doSend()方法;doSend()以及RocoketMQ所特有的一些方法如异步,单向和顺序等方法直接添加到RoketMQTempalte中,这些方法直接代理调用到RocketMQ的Producer API来进行消息的发送。事务消息发送端对于事务消息的处理,在消息发送端进行了部分的扩展,参考下图的调用关系类图:RocketMQTemplate里加入了一个发送事务消息的方法sendMessageInTransaction(), 并且最终这个方法会代理到RocketMQ的TransactionProducer进行调用,在这个Producer上会注册其关联的TransactionListener实现类,以便在发送消息后能够对TransactionListener里的方法实现进行调用。3.3. 消息消费端实现在消费端Spring-Boot应用启动后,会扫描所有包含@RocketMQMessageListener注解的类(这些类需要集成RocketMQListener接口,并实现onMessage()方法),这个Listener会一对一的被放置到DefaultRocketMQListenerContainer容器对象中,容器对象会根据消费的方式(并发或顺序),将RocketMQListener封装到具体的RocketMQ内部的并发或者顺序接口实现。在容器中创建RocketMQ Consumer对象,启动并监听定制的Topic消息,如果有消费消息,则回调到Listener的onMessage()方法。使用示例上面的一章介绍了RocketMQ在spring-boot-starter方式的实现,这里通过一个最简单的消息发送和消费的例子来介绍如何使这个rocketmq-spring-boot-starter。4.1 RocketMQ服务端的准备启动NameServer和Broker要验证RocketMQ的Spring-Boot客户端,首先要确保RocketMQ服务正确的下载并启动。可以参考RocketMQ主站的快速开始来进行操作。确保启动NameServer和Broker已经正确启动。创建实例中所需要的Topics在执行启动命令的目录下执行下面的命令行操作bash bin/mqadmin updateTopic -c DefaultCluster -t string-topic4.2. 编译rocketmq-spring-boot-starter目前的spring-boot-starter依赖还没有提交的Maven的中心库,用户使用前需要自行下载git源码,然后执行mvn clean install 安装到本地仓库。git clone https://github.com/apache/rocketmq-externals.gitcd rocketmq-spring-boot-startermvn clean install4.3. 编写客户端代码用户如果使用它,需要在消息的发布和消费客户端的maven配置文件pom.xml中添加如下的依赖:<properties> <spring-boot-starter-rocketmq-version>1.0.0-SNAPSHOT</spring-boot-starter-rocketmq-version></properties><dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>spring-boot-starter-rocketmq</artifactId> <version>${spring-boot-starter-rocketmq-version}</version></dependency>属性spring-boot-starter-rocketmq-version的取值为:1.0.0-SNAPSHOT, 这与上一步骤中执行安装到本地仓库的版本一致。消息发送端的代码发送端的配置文件application.properties# 定义name-server地址spring.rocketmq.name-server=localhost:9876# 定义发布者组名spring.rocketmq.producer.group=my-group1# 定义要发送的topicspring.rocketmq.topic=string-topic发送端的Java代码import org.apache.rocketmq.spring.starter.core.RocketMQTemplate;…@SpringBootApplicationpublic class ProducerApplication implements CommandLineRunner { // 声明并引用RocketMQTemplate @Resource private RocketMQTemplate rocketMQTemplate; // 使用application.properties里定义的topic属性 @Value("${spring.rocketmq.springTopic}") private String springTopic; public static void main(String[] args){ SpringApplication.run(ProducerApplication.class, args); } public void run(String… args) throws Exception { // 以同步的方式发送字符串消息给指定的topic SendResult sendResult = rocketMQTemplate.syncSend(springTopic, “Hello, World!”); // 打印发送结果信息 System.out.printf(“string-topic syncSend1 sendResult=%s %n”, sendResult); }}消息消费端代码消费端的配置文件application.properties# 定义name-server地址spring.rocketmq.name-server=localhost:9876# 定义发布者组名spring.rocketmq.consumer.group=my-customer-group1# 定义要发送的topicspring.rocketmq.topic=string-topic消费端的Java代码@SpringBootApplicationpublic class ConsumerApplication { public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); }}// 声明消费消息的类,并在注解中指定,相关的消费信息@Service@RocketMQMessageListener(topic = “${spring.rocketmq.topic}”, consumerGroup = “${spring.rocketmq.consumer.group}")class StringConsumer implements RocketMQListener<String> { @Override public void onMessage(String message) { System.out.printf(”——- StringConsumer received: %s %f", message); }}这里只是简单的介绍了使用spring-boot来编写最基本的消息发送和接收的代码,如果需要了解更多的调用方式,如: 异步发送,对象消息体,指定tag标签以及指定事务消息,请参看github的说明文档和详细的代码。我们后续还会对这些高级功能进行陆续的介绍。预告:近期还会推出第二篇文章解读springboot框架下消息事务的用法。参考文档1.Spring Boot features-Messaging2.Enterprise Integration Pattern-组成简介3.Spring Cloud Stream Reference Guide4.https://dzone.com/articles/creating-custom-springboot-starter-for-twitter4j本文作者:中间件小哥阅读原文本文为云栖社区原创内容,未经允许不得转载。 ...

November 29, 2018 · 2 min · jiezi

以中间件,路由,跨进程事件的姿势使用WebSocket

通过参考koa中间件,socket.io远程事件调用,以一种新的姿势来使用WebSocket。浏览器端浏览器端使用WebSocket很简单// Create WebSocket connection.const socket = new WebSocket(‘ws://localhost:8080’);// Connection openedsocket.addEventListener(‘open’, function (event) { socket.send(‘Hello Server!’);});// Listen for messagessocket.addEventListener(‘message’, function (event) { console.log(‘Message from server ‘, event.data);});MDN关于WebSocket的介绍能注册的事件有onclose,onerror,onmessage,onopen。用的比较多的是onmessage,从服务器接受到数据后,会触发message事件。通过注册相应的事件处理函数,可以根据后端推送的数据做相应的操作。如果只是写个demo,单单输出后端推送的信息,如下使用即可:socket.addEventListener(‘message’, function (event) { console.log(‘Message from server ‘, event.data);});实际使用过程中,我们需要判断后端推送的数据然后执行相应的操作。比如聊天室应用中,需要判断消息是广播的还是私聊的或者群聊的,以及是纯文字信息还是图片等多媒体信息。这时message处理函数里可能就是一堆的if else。那么有没有什么别的优雅的姿势呢?答案就是中间件与事件,跨进程的事件的发布与订阅。在说远程事件发布订阅之前,需要先从中间件开始,因为后面实现的远程事件发布订阅是基于中间件的。中间件前面说了,在WebSocket实例上可以注册事件有onclose,onerror,onmessage,onopen。每一个事件的处理函数里可能需要做各种判断,特别是message事件。参考koa,可以将事件处理函数以中间件方式来进行使用,将不同的操作逻辑分发到不同的中间件中,比如聊天室应用中,聊天信息与系统信息(比如用户登录属于系统信息)是可以放到不同的中间件中处理的。koa提供use接口来注册中间件。我们针对不同的事件提供相应的中间件注册接口,并且对原生的WebSocket做封装。export default class EasySocket{ constructor(config) { this.url = config.url; this.openMiddleware = []; this.closeMiddleware = []; this.messageMiddleware = []; this.errorMiddleware = []; this.openFn = Promise.resolve(); this.closeFn = Promise.resolve(); this.messageFn = Promise.resolve(); this.errorFn = Promise.resolve(); } openUse(fn) { this.openMiddleware.push(fn); return this; } closeUse(fn) { this.closeMiddleware.push(fn); return this; } messageUse(fn) { this.messageMiddleware.push(fn); return this; } errorUse(fn) { this.errorMiddleware.push(fn); return this; }}通过xxxUse注册相应的中间件。 xxxMiddleware中就是相应的中间件。xxxFn 中间件通过compose处理后的结构再添加一个connect方法,处理相应的中间件并且实例化原生WebSocketconnect(url) { this.url = url || this.url; if (!this.url) { throw new Error(‘url is required!’); } try { this.socket = new WebSocket(this.url, ’echo-protocol’); } catch (e) { throw e; } this.openFn = compose(this.openMiddleware); this.socket.addEventListener(‘open’, (event) => { let context = { client: this, event }; this.openFn(context).catch(error => { console.log(error) }); }); this.closeFn = compose(this.closeMiddleware); this.socket.addEventListener(‘close’, (event) => { let context = { client: this, event }; this.closeFn(context).then(() => { }).catch(error => { console.log(error) }); }); this.messageFn = compose(this.messageMiddleware); this.socket.addEventListener(‘message’, (event) => { let res; try { res = JSON.parse(event.data); } catch (error) { res = event.data; } let context = { client: this, event, res }; this.messageFn(context).then(() => { }).catch(error => { console.log(error) }); }); this.errorFn = compose(this.errorMiddleware); this.socket.addEventListener(’error’, (event) => { let context = { client: this, event }; this.errorFn(context).then(() => { }).catch(error => { console.log(error) }); }); return this; }使用koa-compose模块处理中间件。注意context传入了哪些东西,后续定义中间件的时候都已使用。compose的作用可看这篇文章 傻瓜式解读koa中间件处理模块koa-compose然后就可以使用了:new EasySocket() .openUse((context, next) => { console.log(“open”); next(); }) .closeUse((context, next) => { console.log(“close”); next(); }) .errorUse((context, next) => { console.log(“error”, context.event); next(); }) .messageUse((context, next) => { //用户登录处理中间件 if (context.res.action === ‘userEnter’) { console.log(context.res.user.name+’ 进入聊天室’); } next(); }) .messageUse((context, next) => { //创建房间处理中间件 if (context.res.action === ‘createRoom’) { console.log(‘创建房间 ‘+context.res.room.anme); } next(); }) .connect(‘ws://localhost:8080’)可以看到,用户登录与创建房间的逻辑放到两个中间件中分开处理。不足之处就是每个中间件都要判断context.res.action,而这个context.res就是后端返回的数据。怎么消除这个频繁的if判断呢? 我们实现一个简单的消息处理路由。路由定义消息路由中间件messageRouteMiddleware.jsexport default (routes) => { return async (context, next) => { if (routes[context.req.action]) { await routescontext.req.action; } else { console.log(context.req) next(); } }}定义路由router.jsexport default { userEnter:function(context,next){ console.log(context.res.user.name+’ 进入聊天室’); next(); }, createRoom:function(context,next){ console.log(‘创建房间 ‘+context.res.room.anme); next(); }}使用:new EasySocket() .openUse((context, next) => { console.log(“open”); next(); }) .closeUse((context, next) => { console.log(“close”); next(); }) .errorUse((context, next) => { console.log(“error”, context.event); next(); }) .messageUse(messageRouteMiddleware(router))//使用消息路由中间件,并传入定义好的路由 .connect(‘ws://localhost:8080’)一切都变得美好了,感觉就像在使用koa。想一个问题,当接收到后端推送的消息时,我们需要做相应的DOM操作。比如路由里面定义的userEnter,我们可能需要在对应的函数里操作用户列表的DOM,追加新用户。这使用原生JS或JQ都是没有问题的,但是如果使用vue,react这些,因为是组件化的,用户列表可能就是一个组件,怎么访问到这个组件实例呢?(当然也可以访问vuex,redux的store,但是并不是所有组件的数据都是用store管理的)。我们需要一个运行时注册中间件的功能,然后在组件的相应的生命周期钩子里注册中间件并且传入组件实例运行时注册中间件,修改如下代码:messageUse(fn, runtime) { this.messageMiddleware.push(fn); if (runtime) { this.messageFn = compose(this.messageMiddleware); } return this; }修改 messageRouteMiddleware.jsexport default (routes,component) => { return async (context, next) => { if (routes[context.req.action]) { context.component=component;//将组件实例挂到context下 await routescontext.req.action; } else { console.log(context.req) next(); } }}类似vue mounted中使用mounted(){ let client = this.$wsClients.get(“im”);//获取指定EasySocket实例 client.messageUse(messageRouteMiddleware(router,this),true)//运行时注册中间件,并传入定义好的路由以及当前组件中的this}路由中通过 context.component 即可访问到当前组件。完美了吗?每次组件mounted 都注册一次中间件,问题很大。所以需要一个判断中间件是否已经注册的功能。也就是一个支持具名注册中间件的功能。这里就暂时不实现了,走另外一条路,也就是之前说到的远程事件的发布与订阅,我们也可以称之为跨进程事件。跨进程事件看一段socket.io的代码:Server (app.js)var app = require(‘http’).createServer(handler)var io = require(‘socket.io’)(app);var fs = require(‘fs’);app.listen(80);function handler (req, res) { fs.readFile(__dirname + ‘/index.html’, function (err, data) { if (err) { res.writeHead(500); return res.end(‘Error loading index.html’); } res.writeHead(200); res.end(data); });}io.on(‘connection’, function (socket) { socket.emit(’news’, { hello: ‘world’ }); socket.on(‘my other event’, function (data) { console.log(data); });});Client (index.html)<script src="/socket.io/socket.io.js"></script><script> var socket = io(‘http://localhost’); socket.on(’news’, function (data) { console.log(data); socket.emit(‘my other event’, { my: ‘data’ }); });</script>注意力转到这两部分:服务端 socket.emit(’news’, { hello: ‘world’ }); socket.on(‘my other event’, function (data) { console.log(data); });客户端 var socket = io(‘http://localhost’); socket.on(’news’, function (data) { console.log(data); socket.emit(‘my other event’, { my: ‘data’ }); });使用事件,客户端通过on订阅’news’事件,并且当触发‘new’事件的时候通过emit发布’my other event’事件。服务端在用户连接的时候发布’news’事件,并且订阅’my other event’事件。一般我们使用事件的时候,都是在同一个页面中on和emit。而socket.io的神奇之处就是同一事件的on和emit是分别在客户端和服务端,这就是跨进程的事件。那么,在某一端emit某个事件的时候,另一端如果on监听了此事件,是如何知道这个事件emit(发布)了呢?没有看socket.io源码之前,我设想应该是emit方法里做了某些事情。就像java或c#,实现rpc的时候,可以依据接口定义动态生成实现(也称为代理),动态实现的(代理)方法中,就会将当前方法名称以及参数通过相应协议进行序列化,然后通过http或者tcp等网络协议传输到RPC服务端,服务端进行反序列化,通过反射等技术调用本地实现,并返回执行结果给客户端。客户端拿到结果后,整个调用完成,就像调用本地方法一样实现了远程方法的调用。看了socket.io emit的代码实现后,思路也是大同小异,通过将当前emit的事件名和参数按一定规则组合成数据,然后将数据通过WebSocket的send方法发送出去。接收端按规则取到事件名和参数,然后本地触发emit。(注意远程emit和本地emit,socket.io中直接调用的是远程emit)。下面是实现代码,事件直接用的emitter模块,并且为了能自定义emit事件名和参数组合规则,以中间件的方式提供处理方法:export default class EasySocket extends Emitter{//继承Emitter constructor(config) { this.url = config.url; this.openMiddleware = []; this.closeMiddleware = []; this.messageMiddleware = []; this.errorMiddleware = []; this.remoteEmitMiddleware = [];//新增的部分 this.openFn = Promise.resolve(); this.closeFn = Promise.resolve(); this.messageFn = Promise.resolve(); this.errorFn = Promise.resolve(); this.remoteEmitFn = Promise.resolve();//新增的部分 } openUse(fn) { this.openMiddleware.push(fn); return this; } closeUse(fn) { this.closeMiddleware.push(fn); return this; } messageUse(fn) { this.messageMiddleware.push(fn); return this; } errorUse(fn) { this.errorMiddleware.push(fn); return this; } //新增的部分 remoteEmitUse(fn, runtime) { this.remoteEmitMiddleware.push(fn); if (runtime) { this.remoteEmitFn = compose(this.remoteEmitMiddleware); } return this; } connect(url) { … //新增部分 this.remoteEmitFn = compose(this.remoteEmitMiddleware); } //重写emit方法,支持本地调用以远程调用 emit(event, args, isLocal = false) { let arr = [event, args]; if (isLocal) { super.emit.apply(this, arr); return this; } let evt = { event: event, args: args } let remoteEmitContext = { client: this, event: evt }; this.remoteEmitFn(remoteEmitContext).catch(error => { console.log(error) }) return this; }}下面是一个简单的处理中间件:client.remoteEmitUse((context, next) => { let client = context.client; let event = context.event; if (client.socket.readyState !== 1) { alert(“连接已断开!”); } else { client.socket.send(JSON.stringify({ type: ’event’, event: event.event, args: event.args })); next(); } })意味着调用client.emit(‘chatMessage’,{ from:‘admin’, masg:“Hello WebSocket”});就会组合成数据{ type: ’event’, event: ‘chatMessage’, args: { from:‘admin’, masg:“Hello WebSocket” }}发送出去。服务端接受到这样的数据,可以做相应的数据处理(后面会使用nodejs实现类似的编程模式),也可以直接发送给别的客户端。客户受到类似的数据,可以写专门的中间件进行处理,比如:client.messageUse((context, next) => { if (context.res.type === ’event’) { context.client.emit(context.res.event, context.res.args, true);//注意这里的emit是本地emit。 } next();})如果本地订阅的chatMessage事件,回到函数就会被触发。在vue或react中使用,也会比之前使用路由的方式简单mounted() { let client = this.$wsClients.get(“im”); client.on(“chatMessage”, data => { let isSelf = data.from.id == this.user.id; let msg = { name: data.from.name, msg: data.msg, createdDate: data.createdDate, isSelf }; this.broadcastMessageList.push(msg); });}组件销毁的时候移除相应的事件订阅即可,或者清空所有事件订阅destroyed() { let client = this.$wsClients.get(“im”); client.removeAllListeners();}心跳重连核心代码直接从websocket-heartbeat-js copy过来的(用npm包,还得在它的基础上再包一层),相关文章 初探和实现websocket心跳重连。核心代码: heartCheck() { this.heartReset(); this.heartStart(); } heartStart() { this.pingTimeoutId = setTimeout(() => { //这里发送一个心跳,后端收到后,返回一个心跳消息 this.socket.send(this.pingMsg); //接收到心跳信息说明连接正常,会执行heartCheck(),重置心跳(清除下面定时器) this.pongTimeoutId = setTimeout(() => { //此定时器有运行的机会,说明发送ping后,设置的超时时间内未收到返回信息 this.socket.close();//不直接调用reconnect,避免旧WebSocket实例没有真正关闭,导致不可预料的问题 }, this.pongTimeout); }, this.pingTimeout); } heartReset() { clearTimeout(this.pingTimeoutId); clearTimeout(this.pongTimeoutId); }最后源码地址:easy-socket-browsernodejs实现的类似的编程模式(有空再细说):easy-socket-node实现的聊天室例子:online chat demo 聊天室前端源码:lazy-mock-im聊天室服务端源码:lazy-mock ...

November 5, 2018 · 4 min · jiezi

傻瓜式解读koa中间件处理模块koa-compose

最近需要单独使用到koa-compose这个模块,虽然使用koa的时候大致知道中间件的执行流程,但是没仔细研究过源码用起来还是不放心(主要是这个模块代码少,多的话也没兴趣去研究了)。koa-compose看起来代码少,但是确实绕。闭包,递归,Promise。。。看了一遍脑子里绕不清楚。看了网上几篇解读文章,都是针对单行代码做解释,还是绕不清楚。最后只好采取一种傻瓜的方式:koa-compose去掉一些注释,类型校验后,源码如下:function compose (middleware) { return function (context, next) { // last called middleware # let index = -1 return dispatch(0) function dispatch (i) { if (i <= index) return Promise.reject(new Error(’next() called multiple times’)) index = i let fn = middleware[i] if (i === middleware.length) fn = next if (!fn) return Promise.resolve() try { return Promise.resolve(fn(context, dispatch.bind(null, i + 1))); } catch (err) { return Promise.reject(err) } } }}写出如下代码:var index = -1;function compose() { return dispatch(0)}function dispatch (i) { if (i <= index) return Promise.reject(new Error(’next() called multiple times’)) index = i var fn = middleware[i] if (i === middleware.length) fn = next if (!fn) return Promise.resolve(‘fn is undefined’) try { return Promise.resolve(fn(context, dispatch.bind(null, i + 1))); } catch (err) { return Promise.reject(err) } } function f1(context,next){ console.log(‘middleware 1’); next().then(data=>console.log(data)); console.log(‘middleware 1’); return ‘middleware 1 return’; } function f2(context,next){ console.log(‘middleware 2’); next().then(data=>console.log(data)); console.log(‘middleware 2’); return ‘middleware 2 return’; } function f3(context,next){ console.log(‘middleware 3’); next().then(data=>console.log(data)); console.log(‘middleware 3’); return ‘middleware 3 return’; }var middleware=[ f1,f2,f3]var context={};var next=function(context,next){ console.log(‘middleware 4’); next().then(data=>console.log(data)); console.log(‘middleware 4’); return ‘middleware 4 return’;};compose().then(data=>console.log(data));直接运行结果如下:“middleware 1"“middleware 2"“middleware 3"“middleware 4"“middleware 4"“middleware 3"“middleware 2"“middleware 1"“fn is undefined"“middleware 4 return"“middleware 3 return"“middleware 2 return"“middleware 1 return"按着代码运行流程一步步分析:dispatch(0)i==0,index==-1 i>index 往下index=0fn=f1Promise.resolve(f1(context, dispatch.bind(null, 0 + 1))) 这就会执行f1(context, dispatch.bind(null, 0 + 1))进入到f1执行上下文console.log(‘middleware 1’);输出middleware 1next() 其实就是调用dispatch(1) bind的功劳递归开始dispatch(1)i==1,index==0 i>index 往下index=1fn=f2Promise.resolve(f2(context, dispatch.bind(null, 1 + 1))) 这就会执行f2(context, dispatch.bind(null, 1 + 1))进入到f2执行上下文console.log(‘middleware 2’);输出middleware 2next() 其实就是调用dispatch(2)接着递归dispatch(2)i==2,index==1 i>index 往下index=2fn=f3Promise.resolve(f3(context, dispatch.bind(null, 2 + 1))) 这就会执行f3(context, dispatch.bind(null, 2 + 1))进入到f3执行上下文console.log(‘middleware 3’);输出middleware 3next() 其实就是调用dispatch(3)接着递归dispatch(3)i==3,index==2 i>index 往下index=3i === middleware.lengthfn=nextPromise.resolve(next(context, dispatch.bind(null, 3 + 1))) 这就会执行next(context, dispatch.bind(null, 3 + 1))进入到next执行上下文console.log(‘middleware 4’);输出middleware 4next() 其实就是调用dispatch(4)接着递归dispatch(4)i==4,index==3 i>index 往下index=4fn=middleware[4]fn=undefinedreuturn Promise.resolve(‘fn is undefined’) 回到next执行上下文console.log(‘middleware 4’);输出middleware 4return ‘middleware 4 return’Promise.resolve(‘middleware 4 return’)回到f3执行上下文console.log(‘middleware 3’);输出middleware 3return ‘middleware 3 return’Promise.resolve(‘middleware 3 return’)回到f2执行上下文console.log(‘middleware 2’);输出middleware 2return ‘middleware 2 return’Promise.resolve(‘middleware 2 return’)回到f1执行上下文console.log(‘middleware 1’);输出middleware 1return ‘middleware 1 return’Promise.resolve(‘middleware 1 return’)回到全局上下文至此已经输出"middleware 1"“middleware 2"“middleware 3"“middleware 4"“middleware 4"“middleware 3"“middleware 2"“middleware 1"那么"fn is undefined"“middleware 4 return"“middleware 3 return"“middleware 2 return"“middleware 1 return"怎么来的呢回头看一下,每个中间件里都有next().then(data=>console.log(data));按照之前的分析,then里最先拿到结果的应该是next中间件的,而且结果就是Promise.resolve(‘fn is undefined’)的结果,然后分别是f4,f3,f2,f1。那么为什么都是最后才输出呢?Promise.resolve(‘fn is undefined’).then(data=>console.log(data));console.log(‘middleware 4’);运行一下就清楚了或者setTimeout(()=>console.log(‘fn is undefined’),0);console.log(‘middleware 4’);整个调用过程还可以看成是这样的:function composeDetail(){ return Promise.resolve( f1(context,function(){ return Promise.resolve( f2(context,function(){ return Promise.resolve( f3(context,function(){ return Promise.resolve( next(context,function(){ return Promise.resolve(‘fn is undefined’) }) ) }) ) }) ) }) )}composeDetail().then(data=>console.log(data));方法虽蠢,但是compose的作用不言而喻了最后,if (i <= index) return Promise.reject(new Error(’next() called multiple times’))这句代码何时回其作用呢?一个中间件里调用两次next(),按照上面的套路走,相信很快就明白了。 ...

October 29, 2018 · 2 min · jiezi