消息队列和微服务
消息队列和微服务

消息队列和微服务

微服务

服务架构演变

单体应用—->SOA—->Microservice

单体架构

·传统架构(单机系统),一个项目一个工程:比如商品、订单、支付、库存、登录、注册等等,统一部署,一个进程
·all in one的架构方式,把所有的功能单元放在一个应用里。然后把整个应用部署到一台服务器上。如果负载能力不行,将整个应用进行水平复制,进行扩展,然后通过负载均衡实现访问。
·Java实现:JSP、Servlet,打包成一个jar、war部署易于开发和测试:也十分方便部署;当需要扩展时,只需要将war复制多份,然后放到多个服务器
上,再做个负载均衡就可以了。
·如果某个功能模块出问题,有可能全站不可访问,修改Bug后、某模块功能修改或升级后,需要停掉整个服务,重新整体重新打包、部署这个应用war包,功能模块相互之间耦合度高,相互影响,不适合当今互联网业务功能的快速迭代。
·特别是对于一个大型应用,我们不可能吧所有内容都放在一个应用里面,我们如何维护、如何分工合作都是问题。如果项目庞大,管理难度大
·web应用服务器:开源的tomcat、jetty、glassfish。商用的有weblogic、websphere、Jboss

微服务

URL:https://www.martinfowler.com/microservices/

In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.
— James Lewis and Martin Fowler (2014)

·属于SOA(Service Oriented Architecture)的子集
·微服务化的核心就是将传统的一站式应用,根据业务拆分成一个一个的服务,彻底去掉耦合,每一个微服务提供单个业务功能,一个服务只做一件事。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等
·从技术角度讲就是一种小而独立的处理过程,类似与进程的概念,能够自行单独启动或销毁
·微服务架构(分布式系统),各个模块/服务,各自独立出来,”让专业的人干专业的事”,独立部署。分布式系统中,不同的服务可以使用各自独立的数据库。
·服务之间采用轻量级的通信机制(通常是基于HTTP的RESTful API)。
·微服务设计的思想改变了原有的企业研发团队组织架构。传统的研发组织架构是水平架构,前端、后端、DBA、测试分别有自己对应的团队,属于水平团队组织架构。而微服务的设计思想对团队的划分有着一定的影响,使得团队组织架构的划分更倾向于垂直架构,比如用户业务是一个团队来负责,支付业务是一个团队来负责。但实际上在企业中并不会把团队组织架构拆分得这么绝对,垂直
架构只是一种理想的架构
·微服务的实现框架有多种,不同的应用架构,部署方式也有不同

微服务的优缺点

微服务优点:
·每个服务足够内聚,足够小,代码容易理解。这样能聚焦一个简单唯一的业务功能或业务需求。
·开发简单、开发效率提高,一个服务可能就是专业的只干一件事,微服务能够被小团队单独开发,这个小团队可以是2到5人的开发人员组成
·微服务是松耦合的,是有功能意义的服务,无论是在开发阶段或部署阶段都是独立的。
·微服务能使用不同的语言开发
·易于和第三方集成,微服务运行容易且灵活的方式集成自动部署,通过持续集成工具,如:Jenkins、Hudson、Bamboo
·微服务易于被一个开发人员理解、修改和维护,这样小团队能够更关注自己的工作成果,无需通过合作才能体现价值
·微服务允许你利用融合最新技术。微服务只是业务逻辑的代码,不会和HTML/CSS或其他界面组件混合,即前后端分离
·每个微服务都有自己的存储能力,可以有自己的数据库,也可以有统一数据库

微服务缺点:
·微服务把原有的一个项目拆分成多个独立工程,增加了开发、测试、运维、监控等的复杂度
·微服务架构需要保证不同服务之间的数据一致性,引入了分布式事务和异步补偿机制,为设计和开发带来一定挑战
·开发人员和运维需要处理分布式系统的复杂性,需要更强的技术能力
·微服务适用于复杂的大系统,对于小型应用使用微服务,进行盲目的拆分只会增加其维护和开发成本

微服务技术栈

常见的微服务框架

Dubbo
·阿里开源贡献给了ASF,目前已经是Apache的顶级项目
·一款高性能的Java RPC服务框架,微服务生态体系中的一个重要组件
·将单体程序分解成多个功能服务模块,模块间使用Dubbo框架提供的高性能RPC通信
·内部协调使用 Zookeeper,实现服务注册、服务发现和服务治理
Spring cloud
·一个完整的微服务解决方案,相当于Dubbo的超集
·微服务框架,将单体应用拆分为粒度更小的单一功能服务
·基于HTTP协议的REST(Representational State Transfer 表述性状态转移)风格实现模块间通信

ZooKeeper

ZooKeeper 介绍

ZooKeeper 的由来
下面这段内容摘自《从Paxos到Zookeeper 》第四章第一节的某段内容:

Zookeeper最早起源于雅虎研究院的一个研究小组。在当时,研究人员发现,在雅虎内部很多大型系统基本都需要依赖一个类似的系统来进行分布式协调,但是这些系统往往都存在分布式单点问题。所以,雅虎的开发人员就试图开发一个通用的无单点问题的分布式协调框架,以便让开发人员将精力集中在处理业务逻辑上。
关于“ZooKeeper”这个项目的名字,其实也有一段趣闻。在立项初期,考虑到之前内部很多项目都是使用动物的名字来命名的(例如著名的Pig项目),雅虎的工程师希望给这个项目也取一个动物的名字。时任研究院的首席科学家RaghuRamakrishnan开玩笑地说:“在这样下去,我们这儿就变成动物园了!”此话一出,大家纷纷表示就叫动物园管理员吧一一一因为各个以动物命名的分布式组件放在一起,雅虎的整个分布式系统看上去就像一个大型的动物园了,而Zookeeper正好要用来进行分布式环境的协调一一于是,Zookeeper的名字也就由此诞生了。

ZooKeeper 是一个开源的分布式协调服务,ZooKeeper框架最初是在“Yahoo!”上构建的,用于以简单而稳健的方式访问他们的应用程序。 后来,Apache ZooKeeper成为Hadoop,HBase和其他分布式框架使用的有组织服务的标准。 例如,Apache HBase使用ZooKeeper跟踪分布式数据的状态。ZooKeeper的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。

ZooKeeper 是一个典型的分布式数据一致性解决方案,分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。

Zookeeper 一个最常用的使用场景就是用于担任服务生产者和服务消费者的注册中心(提供发布订阅服务)。 服务生产者将自己提供的服务注册到Zookeeper中心,服务的消费者在进行服务调用的时候先到Zookeeper中查找服务,获取到服务生产者的详细信息之后,再去调用服务生产者的内容与数据。在Dubbo架构中 Zookeeper 就担任了注册中心这一角色。

官网:https://zookeeper.apache.org/

官方文档:https://zookeeper.apache.org/doc/

ZooKeeper 工作原理

ZooKeeper 是一个分布式服务框架,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:命名服务、状态同步、配置中心、集群管理等。

ZooKeeper 功能

命名服务

命名服务是分布式系统中比较常见的一类场景。命名服务是分布式系统最基本的公共服务之一。在分布式系统中,被命名的实体通常可以是集群中的机器、提供的服务地址或远程对象等——这些我们都可以统称它们为名字(Name),其中较为常见的就是一些分布式服务框架(如RPC、RMI)中的服务地址列表,通过使用命名服务,客户端应用能够根据指定名字来获取资源的实体、服务地址和提供者的信息等。

Zookeeper 数据模型

在 Zookeeper 中,节点分为两类
第一类是指构成Zookeeper集群的主机,称之为主机节点
第二类则是指内存中zookeeper数据模型中的数据单元,用来存储各种数据内容,称之为数据节点 ZNode。
Zookeeper内部维护了一个层次关系(树状结构)的数据模型,它的表现形式类似于Linux的文件系统,甚至操作的种类都一致。
Zookeeper数据模型中有自己的根目录(/),根目录下有多个子目录,每个子目录后面有若干个文件,由斜杠(/)进行分割的路径,就是一个ZNode,每个 ZNode上都会保存自己的数据内容和一系列属性信息.
状态同步

每个节点除了存储数据内容和 node 节点状态信息之外,还存储了已经注册的APP 的状态信息,当有些节点或APP 不可用,就将当前状态同步给其他服务。

配置中心

现在我们大多数应用都是采用的是分布式开发的应用,搭建到不同的服务器上,我们的配置文件,同一个应用程序的配置文件一样,还有就是多个程序存在相同的配置,当我们配置文件中有个配置属性需要改变,我们需要改变每个程序的配置属性,这样会很麻烦的去修改配置,那么可用使用ZooKeeper 来实现配置中心, ZooKeeper 采用的是推拉相结合的方式:客户端向服务端注册自己需要关注的节点,一旦该节点的数据发生变更,那么服务端就会向相应的客户端发送Watcher事件通知,客户端接收到这个消息通知后,需要主动到服务端获取最新的数据。Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,此应用比较流行

集群管理

所谓集群管理,包括集群监控与集群控制两大块,前者侧重对集群运行时状态的收集,后者则是对集群进行操作与控制,在日常开发和运维过程中,我们经常会有类似于如下的需求:
希望知道当前集群中究竟有多少机器在工作。
对集群中每台机器的运行时状态进行数据收集。对集群中机器进行上下线操作。

ZooKeeper 具有以下两大特性:
客户端如果对ZooKeeper 的一个数据节点注册 Watcher监听,那么当该数据节点的内容或是其子节点列表发生变更时,ZooKeeper服务器就会向已注册订阅的客户端发送变更通知。
对在ZooKeeper上创建的临时节点,一旦客户端与服务器之间的会话失效,那么该临时节点也就被自动清除。

Watcher(事件监听器)是 Zookeeper 中的一个很重要的特性。Zookeeper 允许用户在指定节点上注册一些 Watcher,并且在一些特定事件触发的时候, ZooKeeper 服务端会将事件通知到感兴趣的客户端上去,该机制是 Zookeeper 实现分布式协调服务的重要特性。

ZooKeeper 服务流程

1. 生产者启动
2. 生产者注册至zookeeper
3. 消费者启动并订阅频道
4. zookeeper 通知消费者事件
5. 消费者调用生产者
6. 监控中心负责统计和监控服务状态

ZooKeeper 单机部署

单机版的 ZooKeeper 安装

官方文档:https://zookeeper.apache.org/doc/r3.6.2/zookeeperStarted.html#sc_InstallingSingleMode

配置 Java 环境

官方依赖介绍:https://zookeeper.apache.org/doc/r3.6.2/zookeeperAdmin.html#sc_requiredSoftware

[root@ubuntu2004 ~]#cat install_zookeeper_single_node.sh
#!/bin/bash
#
#********************************************************************
#Author:            shuhong
#QQ:                985347841
#Date:              2022-11-07
#FileName:          install_zookeeper_single_node.sh
#URL:               hhhhh
#Description:       The test script
#Copyright (C):     2022 All rights reserved
#********************************************************************
ZK_VERSION=3.8.0
#ZK_VERSION=3.6.3
#ZK_VERSION=3.7.1
ZK_URL=https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-${ZK_VERSION}/apache-zookeeper-${ZK_VERSION}-bin.tar.gz
#ZK_URL="https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/stable/apache-zookeeper-${ZK_VERSION}-bin.tar.gz"
#ZK_URL="https://downloads.apache.org/zookeeper/stable/apache-zookeeper-${ZK_VERSION}-bin.tar.gz"

INSTALL_DIR=/usr/local/zookeeper


HOST=hostname -I|awk '{print $1}'

.  /etc/os-release

color () {
    RES_COL=60
    MOVE_TO_COL="echo -en \\033[${RES_COL}G"
    SETCOLOR_SUCCESS="echo -en \\033[1;32m"
    SETCOLOR_FAILURE="echo -en \\033[1;31m"
    SETCOLOR_WARNING="echo -en \\033[1;33m"
    SETCOLOR_NORMAL="echo -en \E[0m"
    echo -n "$1" && $MOVE_TO_COL
    echo -n "["
    if [ $2 = "success" -o $2 = "0" ] ;then
        ${SETCOLOR_SUCCESS}
        echo -n $"  OK  "    
    elif [ $2 = "failure" -o $2 = "1"  ] ;then 
        ${SETCOLOR_FAILURE}
        echo -n $"FAILED"
    else
        ${SETCOLOR_WARNING}
        echo -n $"WARNING"
    fi
    ${SETCOLOR_NORMAL}
    echo -n "]"
    echo 
}


install_jdk() {
    if [ $ID = 'centos' -o  $ID = 'rocky' ];then
        yum -y install java-1.8.0-openjdk-devel || { color "安装JDK失败!" 1; exit 1; }
    else
        apt update
        apt install openjdk-11-jdk -y || { color "安装JDK失败!" 1; exit 1; } 
        #apt install openjdk-8-jdk -y || { color "安装JDK失败!" 1; exit 1; } 
    fi
    java -version
}


install_zookeeper() {
    wget -P /usr/local/src/ --no-check-certificate $ZK_URL || { color  "下载失败!" 1 ;exit ; }
    tar xf /usr/local/src/${ZK_URL##*/} -C /usr/local
    ln -s /usr/local/apache-zookeeper-*-bin/ ${INSTALL_DIR}
    echo "PATH=${INSTALL_DIR}/bin:$PATH" >  /etc/profile.d/zookeeper.sh
    .  /etc/profile.d/zookeeper.sh
    mkdir -p ${INSTALL_DIR}/data 
    cat > ${INSTALL_DIR}/conf/zoo.cfg <<EOF
tickTime=2000
initLimit=10
syncLimit=5
dataDir=${INSTALL_DIR}/data
clientPort=2181
maxClientCnxns=128
autopurge.snapRetainCount=3
autopurge.purgeInterval=24
EOF
    cat > /lib/systemd/system/zookeeper.service <<EOF
[Unit]
Description=zookeeper.service
After=network.target

[Service]
Type=forking
#Environment=${INSTALL_DIR}
ExecStart=${INSTALL_DIR}/bin/zkServer.sh start
ExecStop=${INSTALL_DIR}/bin/zkServer.sh stop
ExecReload=${INSTALL_DIR}/bin/zkServer.sh restart

[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload
    systemctl enable --now  zookeeper.service
    systemctl is-active zookeeper.service
    if [ $? -eq 0 ] ;then 
        color "zookeeper 安装成功!" 0  
    else 
        color "zookeeper 安装失败!" 1
        exit 1
    fi   
}


install_jdk

install_zookeeper
[root@ubuntu2004 ~]#bash install_zookeeper_single_node.sh 
.....
Created symlink /etc/systemd/system/multi-user.target.wants/zookeeper.service → /lib/systemd/system/zookeeper.service.
active
zookeeper 安装成功!                                        [  OK  ]

[root@ubuntu2004 ~]#systemctl status zookeeper.service 
● zookeeper.service
     Loaded: loaded (/lib/systemd/system/zookeeper.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2022-11-07 17:44:08 CST; 45s ago
    Process: 5627 ExecStart=/usr/local/zookeeper/bin/zkServer.sh start (code=exited, status=0/SUCCESS)
   Main PID: 5658 (java)
...
[root@ubuntu2004 ~]#ss -ntlp
State               Recv-Q              Send-Q                             Local Address:Port                              Peer Address:Port              Process                                                 
LISTEN              0                   4096                               127.0.0.53%lo:53                                     0.0.0.0:*                  users:(("systemd-resolve",pid=735,fd=13))              
LISTEN              0                   128                                      0.0.0.0:22                                     0.0.0.0:*                  users:(("sshd",pid=768,fd=3))                          
LISTEN              0                   128                                         [::]:22                                        [::]:*                  users:(("sshd",pid=768,fd=4))                          
LISTEN              0                   50                                             *:2181                                         *:*                  users:(("java",pid=5658,fd=57))                        
LISTEN              0                   50                                             *:33005                                        *:*                  users:(("java",pid=5658,fd=48))                        
LISTEN              0                   50                                             *:8080                                         *:*                  users:(("java",pid=5658,fd=49))   

ZooKeeper 集群部署

ZooKeeper 集群介绍

ZooKeeper集群用于解决单点和单机性能及数据高可用等问题

zookeeper集群基于Master/Slave的模型,处于主要地位(处理写操作)的主机称为Master(Leader)节点,处于次要地位(处理读操作)的主机称为 slave节点,生产中读取的方式一般是以异步复制方式来实现的。
对于n台server,每个server都知道彼此的存在。只要有>n/2台server节点可用,整个zookeeper系统保持可用。
因此zookeeper集群通常由奇数台Server节点组成
当进行写操作时,由Master(leader)完成,并且同步到其它Slave(follower)节点,当在保证写操作在所有节点的总数过半后,才会认为写操作成功

官方链接:http://zookeeper.apache.org/doc/r3.7.0/zookeeperOver.html

集群角色

Kafka

消息队列简介

消息队列历史
1983 年在MIT 工作的26岁的印度小伙 Vivek Ranadive突发奇想,以前我们的软件相互通信,都是点对点的,而且要实现相同的协议,能不能有一种专门用来通信的中间件,就像主板(BUS)一样,把不同的软件集成起来呢?于是他搞了一家公司(Teknekron),开发了世界上第一个消息队列软件TheInformation Bus(TIB)。最开始的时候,它被高盛这些公司用在金融交易里面。因为TIB 实现了发布订阅(Publish/Subscribe)模型,信息的生产者和消费者可以完全解耦,这个特性引起了电信行业特别是新闻机构的注意。1994年路透社收购了Teknekron。

TIB 的成功马上引起了业界大佬IBM 的注意,他们研发了自己的IBM MQ(IBMWesphere)。后面微软也加入了这场战斗,研发了MSMQ。这个时候,每个厂商的产品是孤立的,大家都有自己的技术壁垒。比如一个应用订阅了IBM MQ 的消息,如果有要订阅MSMQ 的消息,因为协议、API 不同,又要重复去实现。

JDBC 协议大家非常熟悉吧?J2EE 制定了JDBC 的规范,那么那么各个数据库厂商自己去实现协议,提供jar 包,在Java 里面就可以使用相同的API 做操作不同的数据库了。MQ 产品的问题也是一样的,2001年的时候,SUN 公司发布了 JMS 规范,它想要在各大厂商的MQ 上面统一包装一层Java 的规范,大家都只需要针对API 编程就可以了,不需要关注使用了什么样的消息中间件,只要选择合适的MQ 驱动。但是JMS 只适用于Java 语言,它是跟语言绑定的,没有从根本上解决这个问题(只是一个API)。

所以在2006 年的时候,AMQP 规范发布了。它是跨语言和跨平台的,真正地促进了消息队列的繁荣发展。
2007 年的时候,Rabbit 技术公司基于Erlang语言开发了符合AMQP 规范RabbitMQ 1.0。

从最开始用在金融行业里面,现在RabbitMQ 已经在世界各地的公司中遍地开花。国内的绝大部分大厂都在用RabbitMQ,包括头条,美团,滴滴(TMD),去哪儿,艺龙,淘宝也有用。

MQ 定义

#阿里云消息队列
https://www.aliyun.com/product/ons?spm=5176.234368.h2v3icoap.427.2620db25lcHi1Q&aly_as=Tz_Lue_o

在分布式场景中,相对于大量的用户请求来说,内部的功能主机之间、功能模块之间等,数据传递的数据量是无法想象的,因为一个用户请求,会涉及到各种内部的业务逻辑跳转等操作。那么,在大量用户的业务场景中,如何保证所有的内部业务逻辑请求都处于稳定而且快捷的数据传递呢?消息队列(Message Queue)技术可以满足此需求

消息队列(Message Queue,简称 MQ)是构建分布式互联网应用的基础设施,通过 MQ 实现的松耦合架构设计可以提高系统可用性以及可扩展性,是适用于现代应用的最佳设计方案。

消息队列是一种异步的服务间通信方式,适用于无服务器和微服务架构。消息在被处理和删除之前一直存储在队列上。每条消息仅可被一位用户处理一次。消息队列可被用于分离重量级处理、缓冲或批处理工作以及缓解高峰期工作负载。

MQ 使用场合

消息队列作为高并发系统的核心组件之一,能够帮助业务系统结构提升开发效率和系统稳定性消息队列主要有以下应用场景
·削峰填谷
诸如电商业务中的秒杀、抢红包、企业开门红等大型活动时皆会带来较高的流量脉冲,或因没做相应的保护而导致系统超负荷甚至崩溃,或因限制太过导致请求大量失败而影响用户体验,消息队列可提供削峰填谷的服务来解决该问题。
·异步解耦
交易系统作为淘宝等电商的最核心的系统,每笔交易订单数据的产生会引起几百个下游业务系统的关注,包括物流、购物车、积分、流计算分析等等,整体业务系统庞大而且复杂,消息队列可实现异步通信和应用解耦,确保主站业务的连续性。
·顺序收发

细数日常中需要保证顺序的应用场景非常多,例如证券交易过程时间优先原则,交易系统中的订单创建、支付、退款等流程,航班中的旅客登机消息处理等等。与先进先出FIFO(First In FirstOut)原理类似,消息队列提供的顺序消息即保证消息FIFO。
·分布式事务一致性
交易系统、支付红包等场景需要确保数据的最终一致性,大量引入消息队列的分布式事务,既可以实现系统之间的解耦,又可以保证最终的数据一致性。
·大数据分析
数据在“流动”中产生价值,传统数据分析大多是基于批量计算模型,而无法做到实时的数据分析,利用消息队列与流式计算引擎相结合,可以很方便的实现业务数据的实时分析。
·分布式缓存同步
电商的大促,各个分会场琳琅满目的商品需要实时感知价格变化,大量并发访问数据库导致会场页面响应时间长,集中式缓存因带宽瓶颈,限制了商品变更的访问流量,通过消息队列构建分布式缓存,实时通知商品数据的变化
·蓄流压测
线上有些链路不方便做压力测试,可以通过堆积一定量消息再放开来压测

主流 MQ

目前主流的消息队列软件有 kafka、RabbitMQ、ActiveMQ、RocketMQ等,还有相对小众的消息队列软件如ZeroMQ、Apache Qpid 等。

Kafka 介绍

阿里云消息队列:https://www.aliyun.com/product/ons?spm=5176.234368.h2v3icoap.427.2620db25lcHi1Q&amp;aly_as=Tz_Lue_o

Kafka 被称为下一代分布式消息系统,由 Scala 和 Java编写,是非营利性组织ASF(Apache SoftwareFoundation)基金会中的一个开源项目,比如:HTTP Server、Tomcat、Hadoop、ActiveMQ等开源软件都属于 Apache基金会的开源软件,类似的消息系统还有RabbitMQ、ActiveMQ、ZeroMQ。
Kafka用于构建实时数据管道和流应用程序。 它具有水平可伸缩性,容错性,快速性,可在数千家组织中同时投入生产协同工作。

官网: http://kafka.apache.org/

常用消息队列对比

官网: http://kafka.apache.org/
3.3 常用消息队列对比
kafka 最主要的优势是其具备分布式功能、并可以结合 zookeeper 可以实现动态扩容,Kafka 是一种高吞吐量的分布式发布订阅消息系统。

ActiveMQRabbitMQKafka
所属公司/公司ApacheMozilla Public LicenseApache/Linkedln
开发语言JavaEriangJava
支持协议OpenWire、STOMP、REST、XMPP、AMQPAMQP仿AMQP
事务支持不支持不支持
集群支持支持支持
负载均衡支持支持支持
动态扩容不支持不支持支持(zk)

Kafka 特点和优势

特点
·分布式: 多机实现,不允许单机
·分区: 一个消息.可以拆分出多个,分别存储在多个位置
·多副本: 防止信息丢失,可以多来几个备份
·多订阅者: 可以有很多应用连接kafka
·Zookeeper: 早期版本的Kafka依赖于zookeeper, 2021年4月19日Kafka 2.8.0正式发布,此版本包括了很多重要改动,最主要的是kafka通过自我管理的仲裁来替代ZooKeeper,即Kafka将不再需要ZooKeeper!

优势
·Kafka 通过 O(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以 TB 级别以上的消息存储也能够保持长时间的稳定性能。
·高吞吐量:即使是非常普通的硬件Kafka也可以支持每秒数百万的消息。支持通过Kafka 服务器分区消息。
·分布式: Kafka 基于分布式集群实现高可用的容错机制,可以实现自动的故障转移
·顺序保证:在大多数使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。 Kafka保证一个Partiton内的消息的有序性(分区间数据是无序的,如果对数据的顺序有要求,应将在创建主题时将分区数partitions设置为1)
·支持 Hadoop 并行数据加载
·通常用于大数据场合,传递单条消息比较大,而Rabbitmq 消息主要是传输业务的指令数据,单条数据较小

Kafka 角色和流程

Kafka 角色

Producer:Producer即生产者,消息的产生者,是消息的入口。负责发布消息到Kafka broker。
Consumer:消费者,用于消费消息,即处理消息
Consumer group:每个consumer 属于一个特定的consumer group(可为每个consumer 指定 groupname,若不指定 group name 则属于默认的group),使用 consumer high level API 时,同一topic的一条消息只能被同一个consumer group 内的一个consumer 消费,但多个consumer group 可同时消费这一消息。
Broker:Broker是kafka实例,每个服务器上可以有一个或多个kafka的实例,假设每个broker对应一台服务器。每个kafka集群内的broker都有一个不重复的编号,如: broker-0、broker-1等……
Topic:消息的主题,可以理解为消息的分类,相当于Redis的Key和ES中的索引,kafka的数据就保存在topic。在每个broker上都可以创建多个topic。物理上不同 topic 的消息分开存储在不同的文件夹,逻辑上一个 topic的消息虽然保存于一个或多个broker 上, 但用户只需指定消息的topic即可生产或消费数据而不必关心数据存于何处,topic 在逻辑上对record(记录、日志)进行分组保存,消费者需要订阅相应的topic 才能消费topic中的消息。

Replication: 同样数据的副本,包括leader和follower的副本数,基本于数据安全,建议至少2个,是Kafka的高可靠性的保障,和ES不同的,ES中的副本数不包括主分片数
Partition:是物理上的概念,每个topic 分割为一个或多个partition,即一个topic切分为多份.创建topic时可指定 parition 数量,partition的表现形式就是一个一个的文件夹,该文件夹下存储该partition的数据和索引文件,分区的作用还可以实现负载均衡,提高kafka的吞吐量。同一个topic在不同的分区的数据是不重复的,一般Partition数不要超过节点数据,注意同一个partition数据是有顺序的,但不同的partition则是无序的。

为了实现数据的高可用,比如将分区 0 的数据分散到不同的kafka 节点,每一个分区都有一个 broker 作为 Leader 和一个 broker 作为Follower,类似于ES中的主分片和副本分片.
AR: Assigned Replicas,分区中的所有副本的统称,AR= lSR+ OSR
lSR:ln Sync Replicas,所有与leader副本保持同步的副本 follower和leader本身组成的集合,是AR的子集
OSR:out-of-Sync Replied,所有与leader副本同步不能同步的 follower的集合,是AR的子集

分区的优势:
·实现存储空间的横向扩容,即将多个kafka服务器的空间结合利用
·提升性能,多服务器读写
·实现高可用,分区leader 分布在不同的kafka 服务器,假设分区因子为 3, 分区 0 的leader为服务器A,则服务器 B 和服务器 C 为 A 的follower,而分区 1 的leader为服务器B,则服务器 A 和C 为服务器B 的follower,而分区 2 的leader 为C,则服务器A 和 B 为C 的follower。

Kafka 写入消息的流程

Kafka 部署

官方文档:http://kafka.apache.org/quickstart

Dubbo

Dubbo 介绍

Apache Dubbo 是一款高性能、轻量级的开源服务框架
Apache Dubbo 提供了六大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现,高度可扩展能力,运行期流量调度,可视化的服务治理与运维。
阿里云微服务:https://promotion.aliyun.com/ntms/act/edasdubbo.html

Dubbo 官网:https://dubbo.apache.org/zh/

Dubbo 架构:https://dubbo.apache.org/zh/docs/v2.7/user/preface/architecture/

Dubbo 简介:https://help.aliyun.com/document_detail/99299.html

节点角色说明

节点角色说明
Provider暴露服务的服务提供方
Consumer调用远程服务的服务消费方
Registry服务注册与发现的注册中心
Monitor统计服务的调用次数和调用时间的监控中心
Container服务运行容器

调用关系说明
1. 服务容器负责启动,加载,运行服务提供者。
2. 服务提供者在启动时,向注册中心注册自己提供的服务。
3. 服务消费者在启动时,向注册中心订阅自己所需的服务。
4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

中心类型开源组件EDAS
(EnterpriseDistributed ApplicationService)
组件
托管说明
注册中心Nacos(推荐)
ZooKeeper(推荐)
etcdConsulEureka
Nacos(推荐)EDAS注册中只需将应用部署到 EDAS中,
即可默认接入注册中心
配置中心Nacos(推荐)
ZooKeeper(推荐)
Apollo
Nacos(推荐)只需将应用部署到EDAS中,
即可默认接入配置中心
元数据中心Nacos(推荐)
Redis(推荐)
ZooKeeper
Nacos(推荐)您只需将应用部署到EDAS中,
即可默认接入元数据中心。

Dubbo服务框架的工作流程如下:
1. 提供者在启动时,在注册中心注册服务。
2. 消费者在启动时,在注册中心订阅所需的服务。
3. 注册中心返回提供者地址列表给消费者。如果提供者发生变更,注册中心将推送变更数据给消费者。
4. 消费者基于软负载均衡算法,从提供者地址列表中选一个提供者进行调用。
Nacos 介绍

Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

Nacos 官网:https://nacos.io/zh-cn/

实现 Dubbo 架构

官方 Demo:https://github.com/apache/dubbo/tree/master/dubbo-demo