1.分布式系统中的相关概念
1.1 大型互联网项目
传统项目和互联网项目相比:
互联网项目特点:
- 用户多
- 流量大,并发高
- 海量数据
- 易受攻击
- 功能繁琐
- 变更快
- 高性能:提供快速的访问体验
衡量网站的性能指标:
-
响应时间:指执行一个请求从开始到最后收到响应数据所花费的总体时间。
-
并发数:指系统同时能处理的请求数量。
- 并发连接数:指的是客户端向服务器发起请求,并建立了TCP连接。每秒钟服务器连接的总TCP数量
- 请求数:也称为QPS(Query Per Second) 指每秒多少请求.
- 并发用户数:单位时间内有多少用户
-
吞吐量:指单位时间内系统能处理的请求数量。
-
QPS:Query Per Second 每秒查询数。
-
TPS:Transactions Per Second 每秒事务数。
-
一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。
-
一个页面的一次访问,只会形成一个TPS;但一次页面请求,可能产生多次对服务器的请求,就会有多个QPS
QPS >= 并发连接数 >= TPS
-
-
高性能:提供快速的访问体验。
-
高可用:网站服务一直可以正常访问。
-
可伸缩:通过硬件增加/减少,提高/降低处理能力。
-
高可扩展:系统间耦合低,方便的通过新增/移除方式,增加/减少新的功能/模块。
-
安全性:提供网站安全访问和数据加密,安全存储等策略。
-
敏捷性:随需应变,快速响应
1.2 集群和分布式
集群:很多“人”一起 ,干一样的事。
- 一个业务模块,部署在多台服务器上。
分布式:很多“人”一起,干不一样的事。这些不一样的事,合起来是一件大事。
- 一个大的业务系统,拆分为小的业务模块,分别部署在不同的机器上。
举个例子来说,一个餐馆最初只有一个厨师老李,这个厨师精力有限,为了让餐馆做大做强,就又招了一个厨师老王。老李和老王干的活都是一样的,他两人就构成了一个集群,有了这个集群,整个餐馆出菜速度就翻了一倍,实现了高性能。当老李或者老王其中一个生病无法上班时,另一个还可以工作,只是性能稍微低一点而已,实现了高可用。老李和老王是两个大厨,但是有很多时间都浪费在了洗菜、切菜等繁琐工作,所以为了提高其使用价值,又找了几个厨房帮工,专门负责洗菜、切菜等工作,老李老王就负责做菜。这几个人和老李老王的工作是不一样的,它们几个合起来就称作分布式。整体就是分布式集群。当发现洗菜这一环节比较慢时,可以再找几个人专门负责洗菜,这就是可伸缩,即哪一模块效率低,可以进行增加设备。一段时间后出现了自动洗菜机,以后洗菜就不需要人工洗了,那么这几个洗菜人就被淘汰,将机器人引用进来负责洗菜,这就叫高可扩展,即哪一模块过时,可以直接更换而不影响其他模块。
1.3 架构演进
Dubbo 是 SOA时代的产物,SpringCloud 是微服务时代的产物
2. Dubbo概述
2.1 Dubbo概念
Dubbo是阿里巴巴公司开源的一个高性能、轻量级的 Java RPC 框架。
致力于提供高性能和透明化的 RPC 远程服务调用方案,以及 SOA 服务治理方案。
2.2 Dubbo架构
节点角色说明:
- Provider:暴露服务的服务提供方
- Container:服务运行容器
- Consumer:调用远程服务的服务消费方
- Registry:服务注册与发现的注册中心
- Monitor:统计服务的调用次数和调用时间的监控中心
流程:
- 服务提供者运行在一个容器中,需要将容器运行起来。
- 容器运行后,会注册到注册中心,相当于把服务提供者的调用IP等信息上传
- 服务消费者可以通过服务发现,请求拉取服务提供者的信息
- 注册中心将服务提供者的信息通知给服务消费者
- 之后服务消费者调用服务提供者
- 监控中心对服务进行监控,统计服务的调用次数和调用时间
3. Dubbo快速入门
通过上一节我们知道,服务提供者要将信息注册到注册中心。
Dubbo官方推荐使用Zookeeper作为注册中心。(Zookeeper系统学习将在SpringCloud中提到,这里只作为注册中心使用)
3.1 Zookeeper安装
-
环境准备
ZooKeeper服务器是用Java创建的,它运行在JVM之上。需要安装JDK 7或更高版本。
yum -y install java-1.8.0-openjdk
java -version
-
上传
将下载的ZooKeeper放到/opt/ZooKeeper目录下
-
解压
将tar包解压到/opt/zookeeper目录下
tar -zxvf apache-zookeeper-3.5.6-bin.tar.gz
-
修改配置文件
进入解压目录下的conf目录下,发现有一个zoo_sample.cfg文件。这个文件目前是不能生效的,因为配置文件名必须是zoo.cfg文件才能生效
在/opt/zookeeper下创建zkdata目录,作为zookeeper数据目录
[root@VM-24-10-centos zookeeper]# mkdir zkdata [root@VM-24-10-centos zookeeper]# cd zkdata/ [root@VM-24-10-centos zkdata]# pwd /root/opt/zookeeper/zkdata [root@VM-24-10-centos conf]# ls configuration.xsl log4j.properties zoo_sample.cfg [root@VM-24-10-centos conf]# cp zoo_sample.cfg zoo.cfg [root@VM-24-10-centos conf]# vim zoo.cfg # The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit=10 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=5 # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. dataDir=/root/opt/zookeeper/zkdata # the port at which the clients will connect clientPort=2181 # the maximum number of client connections. # increase this if you need to handle more clients #maxClientCnxns=60 :wq
-
启动
进入bin目录,执行zkServer.sh
[root@VM-24-10-centos apache-zookeeper-3.5.6-bin]# cd bin/ [root@VM-24-10-centos bin]# ls README.txt zkCli.sh zkServer.cmd zkTxnLogToolkit.cmd zkCleanup.sh zkEnv.cmd zkServer-initialize.sh zkTxnLogToolkit.sh zkCli.cmd zkEnv.sh zkServer.sh [root@VM-24-10-centos bin]# ./zkServer.sh start /usr/bin/java ZooKeeper JMX enabled by default Using config: /root/opt/zookeeper/apache-zookeeper-3.5.6-bin/bin/../conf/zoo.cfg Starting zookeeper ... STARTED [root@VM-24-10-centos bin]# ./zkServer.sh status /usr/bin/java ZooKeeper JMX enabled by default Using config: /root/opt/zookeeper/apache-zookeeper-3.5.6-bin/bin/../conf/zoo.cfg Client port found: 2181. Client address: localhost. Mode: standalone
3.2 Dubbo入门
创建基础案例:
-
创建模块
创建两个Maven模块,名叫dubbo-service、dubbo-web。web项目依赖于service项目
给两个模块的POM导入坐标,service没有tomcat插件,web打包方式为war其余一样
<properties> <spring.version>5.1.9.RELEASE</spring.version> </properties> <dependencies> <!-- servlet3.0规范的坐标 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!--spring的坐标--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!--springmvc的坐标--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!--日志--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.21</version> </dependency> </dependencies> <build> <plugins> <!--tomcat插件 --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <configuration> <port>8000</port> <path>/</path> </configuration> </plugin> </plugins> </build>
-
改造两个模块,整合Spring、SpringMVC
web模块依赖service模块
<dependency> <groupId>com.mark</groupId> <artifactId>dubbo-service</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
两个模块分别导入配置文件
-
在服务提供者模块编写 UserServiceImpl 提供服务
public interface UserService { public String sayHello(); }
@Service public class UserServiceImpl implements UserService { public String sayHello() { return "Hello dubbo"; } }
-
在服务消费者中的 UserController 远程调用UserServiceImpl 提供的服务
@RestController @RequestMapping("/user") public class UserController { /** * 注入Service */ @Resource private UserService userService; @RequestMapping("/sayHello") public String sayHello(){ return userService.sayHello(); } }
-
分别启动两个服务,测试
使用Maven命令:install安装service
使用Maven命令:运行web中的tomcat插件
访问http://localhost:8000/user/sayHello.do即可看到结果
现在的这个项目还是一个单体的项目,因为两个项目并不能独立运行
改造如下:
-
引入Dubbo和Zookeeper依赖
<properties> ... <dubbo.version>2.7.4.1</dubbo.version> <zookeeper.version>4.0.0</zookeeper.version> </properties> ... <!--Dubbo的起步依赖,版本2.7之后统一为rg.apache.dubb --> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>${dubbo.version}</version> </dependency> <!--ZooKeeper客户端实现 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>${zookeeper.version}</version> </dependency> <!--ZooKeeper客户端实现 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>${zookeeper.version}</version> </dependency>
-
service模块打包方式改为war,并添加tomcat插件
<packaging>war</packaging> ... <build> <plugins> <!--tomcat插件--> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <configuration> <port>9000</port> <path>/</path> </configuration> </plugin> </plugins> </build>
-
改造service层
import org.apache.dubbo.config.annotation.Service; @Service //将该类的对象创建出来,放到Spring的IOC容器中 bean定义 @Service //将这个类提供的方法(服务)对外发布。将访问的地址、IP、路径注册到注册中心 public class UserServiceImpl implements UserService { public String sayHello() { return "Hello dubbo"; } }
配置dubbo
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--dubbo的配置--> <!--1.配置项目的名称,唯一--> <dubbo:application name="dubbo-service"/> <!--2.配置注册中心(zookeeper)的地址--> <dubbo:registry address="zookeeper://xxx.xxx.xx.x:2181"/> <!--3.配置dubbo包扫描--> <dubbo:annotation package="com.mark.service.impl"/> </beans>
添加WEB-INF和web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <!-- spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
-
改造controller层
web取消依赖service
修改代码
@RestController @RequestMapping("/user") public class UserController { /** * 注入Service */ //@Resource//本地注入 /* 1. 从zookeeper注册中心获取userService的访问url 2. 进行远程调用RPC 3. 将结果封装为一个代理对象。给变量赋值 */ @Reference//远程注入 private UserService userService; @RequestMapping("/sayHello") public String sayHello(){ return userService.sayHello(); } }
添加dubbo配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <mvc:annotation-driven/> <context:component-scan base-package="com.mark.controller"/> <!--dubbo的配置--> <!--1.配置项目的名称,唯一--> <dubbo:application name="dubbo-web"/> <!--2.配置注册中心(zookeeper)的地址--> <dubbo:registry address="zookeeper://xxx.xxx.xx.x:2181"/> <!--3.配置dubbo包扫描--> <dubbo:annotation package="com.mark.controller"/> </beans>
测试
4. Dubbo高级特性
待完成
标签:bin,Dubbo,dubbo,zookeeper,org,root From: https://www.cnblogs.com/hackertyper/p/17021800.html