RPC 基础知识
软件架构
繁多利用架构
当网站流量很小时,利用规模小时,只需一个利用,将所有的性能都部署在一起,以缩小部署服务数量和老本。此时,用于简化增删改查工作量的数据拜访框架 (ORM) 是要害。数据库的解决工夫影响利用的性能。
这种后果的利用适宜小型零碎、小型网站、或者企业的外部零碎,用户较少,申请量不大,对申请的解决工夫没有太高的要求。将所有性能都部署到一个服务器,简略易用。开发我的项目的难度低。
但毛病也不言而喻:
- 性能扩大比拟艰难
- 不利于多人同时开发
- 不利于降级保护
- 整个零碎的空间占用比拟大
分布式服务架构
当利用越来越多,利用之间交互不可避免,将外围业务抽取进去,作为独立的服务,逐步造成稳固的服务中心,是前段利用能更疾速的响应多变的市场需求。此时用于进步业务服用及整合的 分布式服务框架(RPC)是要害。分布式系统将服务作为独立的利用,实现服务共享和重用。
分布式系统
什么是分布式系统
分布式系统是若干独立计算机(服务器)的汇合,这些计算机对于用户来说就像单个相干零碎,分布式系统(distributed system) 是建设在网络之上的服务器端的一种构造。
分布式系统中的计算机能够应用不同的操作系统,能够运行不同应用程序提供服务,将服务扩散部署到多个计算机服务器上。
什么是 RPC
RPC(Remote Procedure Call)是指近程过程调用,是一种过程间通信形式,是一种技术思维,而不是标准。它容许程序调用另一个地址空间(网络的另一台机器上)的过程或函数,而不必开发人员显示编码这个调用的细节。调用本地办法和调用近程办法一样。
RPC 的实现办法能够不同,例如 Java 的 rmi
、spring
近程调用等。
RPC 概念是在上世纪 80 年代由Brue Jay Nelson
(布鲁·杰伊·纳尔逊)提出,应用 RPC 能够将本地的调用扩大到近程调用(分布式系统的其余服务器)
RPC 的特点:
- 简略:应用简略,建设分布式应用更容易
- 高效:调用过程看起来非常清晰,效率高
- 通用:过程间通信的形式,有通用的规定
RPC 基本原理
图解
RPC 调用过程
- 调用方 client 要应用右侧 server 的性能(办法),发动对办法的调用
- client stub 是 RPC 中定义的存根,看做是 client 的助手。stub 把要调用的办法参数进行序列化、办法名称和其余数据包装起来
- 通过网络 socket(网络通信的技术),把办法调用的细节内容发送给右侧的 server
- server 端通过 socket 承受申请的办法名称、参数等数据,传给 stub.
- server 端接到的数据由 server stub(server 的助手)解决,来调用 server 的真正办法、解决业务
- server 办法解决完业务,把解决的后果对象(Object)交给了助手,助手把 Object 进行序列化,对象转为二进制数据
- server 助手二进制数据交给网络处理程序
- 通过网络将二进制数据,发送给 client
- client 接到数据,交给 client 助手
- client 助手,接管到数据通过反序列化为 Java 对象(Object),作为近程办法调用后果
RPC 通信是基于 tcp 或 udp 协定
序列化办法(xml/json/ 二进制)
Dubbo 框架
Dubbo 概述
Apache Dubbo 是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大外围能力:
- 面向接口的近程办法调用
- 只能容错和负载平衡
- 服务主动注册和发现
Dubbo 是一个车分布式服务框架,致力于提供高性能和透明化的 RPC 近程服务调用计划及服务治理计划
面向接口代理:
调用接口的办法,在 A 服务器调用 B 服务器的办法,由 Dubbo 实现对 B 的调用,无需关怀实现的细节。
就像 Mybatis 拜访 Dao 接口能够操作数据库一样,不要管线 Dao 接口办法的实现。简化了开发流程和难度。
根本架构
图解
对象角色阐明
- 服务提供者(provider):裸露服务的提供方,服务提供者在启动时,向注册核心注册本人提供的服务。
- 服务消费者(Consumer):调用近程服务的生产方,服务消费者在启动时,向注册核心订阅本人所需的服务。服务消费者从提供者地址列表中,基于软负载平衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 注册核心(Registry):注册核心返回服务提供者地址列表给消费者,如果有变更,注册核心将基于长连贯推送变更数据给消费者
- 监控核心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用工夫,定时每分钟发送一次统计数据到监控核心
调用关系阐明
- 服务容器 负责启动、加载、运行服务提供者
- 服务提供者在启动时,向注册核心注册本人提供的服务
- 服务消费者在启动时,向注册核心订阅本人所需的服务
- 注册核心返回服务提供者地址列表给消费者,如果有变更,注册核心将基于长链接推送变更数据给消费者
- 服务消费者从提供者地址列表中,基于软负载平衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用
- 服务消费者和提供者,在内存中累计调用次数和调用工夫,定时每分钟发送一次统计数据到监控核心
Dubbo 反对的协定
Dubbo 反对多种协定,如:dubbo
、hessian
、rmi
、http
、webservice
、thrift
、memcached
、redis
等
Dubbo 官网举荐应用 dubbo
协定,dubbo 协定默认端口 20880.
应用 dubbo
协定,须要在 spring 配置文件中退出下列标签注解:
<dubbo:protocol name="dubbo" port="20880"
/>
Dubbo 直连实现
- 首先创立一个空的一般 Java 工程
-
创立一个子 maven web 工程
001-link-userService-provider
,最终我的项目目录构造如图所示 -
新建
readme.md
文件,编写我的项目思路1. 创立一个 maven web 工程——服务的提供者 2. 配置 pom.xml 文件——增加须要的依赖 3. 创立一个实体 bean——User 4. 提供一个服务接口——UserService 5. 实现这个服务接口——UserServiceImpl 6. 配置 dubbo 服务提供者的外围配置文件 + 申明 dubbo 服务提供者的名称(保障唯一性)+ 申明 dubbo 应用的协定和端口号 + 裸露服务,应用直连形式 7. 增加监听器
-
编写
pom.xml
文件,增加依赖<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>xyz.rtx3090</groupId> <artifactId>001-link-userService-provider</artifactId> <version>1.0-SNAPSHOT</version> <!--packaging 值默认为 jar--> <packaging>war</packaging> <dependencies> <!--spring 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.16.RELEASE</version> </dependency> <!--dubbo 依赖 --> <!-- https://mvnrepository.com/artifact/com.alibaba/dubbo --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> </dependencies> <build> <plugins> <!-- 规定我的项目 JDK 版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> <resources> <!-- 解决 Maven 动态资源过滤问题 --> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build> </project>
-
新建包
xyz.rtx3090.dubbo.model
,并在其下创立User
实体类package xyz.rtx3090.dubbo.model; import java.io.Serializable; public class User implements Serializable { private Integer id; private String name; private Integer age; //setter and getter public Integer getId() {return id;} public void setId(Integer id) {this.id = id;} public String getName() {return name;} public void setName(String name) {this.name = name;} public Integer getAge() {return age;} public void setAge(Integer age) {this.age = age;} }
-
新建包
xyz.rtx3090.dubbo.service
,并在其下创立UserService
接口类package xyz.rtx3090.dubbo.service; import xyz.rtx3090.dubbo.model.User; public interface UserService { // 依据 id 查问用户信息 User queryUserById(Integer id); }
-
新建包
xyz.rtx3090.dubbo.service.impl
,并在其下创立UserServiceImpl
接口类package xyz.rtx3090.dubbo.service.impl; import xyz.rtx3090.dubbo.model.User; import xyz.rtx3090.dubbo.service.UserService; public class UserServiceImpl implements UserService { @Override public User queryUserById(Integer id) { // 模仿获取长久层中的数据 User user = new User(); user.setId(001); user.setName("Json"); user.setAge(22); return user; } }
-
在
resources
目录创立dubbo-userService-provider.xml
spring 配置文件<?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" 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"> <!-- 服务提供者申明名称:必须保障服务名称的唯一性,它的名称是 dubbo 外部应用的惟一标示 --> <dubbo:application name="001-link-userService-provider"/> <!-- 拜访服务协定的名称及端口号,dubbo 官网举荐应用的是 dubbo 协定,端口号默认为 20880 属性:name: 执行协定的名称 port: 执行协定的端口号(默认为 20880)--> <dubbo:protocol name="dubbo"/> <!-- 裸露服务接口 属性:interface: 裸露服务接口的权限定类名 ref: 接口援用的实现类的 spring 容器中的标示 registry: 如果不应用注册核心,则值为 N /A--> <dubbo:service interface="xyz.rtx3090.dubbo.service.UserService" ref="userService" registry="N/A"/> <!-- 将接口的实现类加载到 spring 容器中 --> <bean id="userService" class="xyz.rtx3090.dubbo.service.impl.UserServiceImpl"/> </beans>
-
编写
web.xml
配置文件<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 注册监听器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo-userService-provider.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
- 正文
pom.xml
文件中的<packaging>war</packaging>
标签,是我的项目打包形式变为默认的jar
,而后在右侧的Maven->Lifecyde->install
把我的项目打包为 Jar 包,最初再勾销<packaging>war</packaging>
标签的注解 -
再创立一个新的 maven web 子工程
002-link-consumer
,最终我的项目目录构造如图所示 -
新建
readme.md
文件,编写我的项目思路1. 创立一个 maven web 工程——服务的消费者 2. 配置 pom 文件——增加须要的依赖 3. 设置 dubbo 的外围配置文件 4. 编写 controller 类 5. 配置 DispatcherServlet 地方调度器
-
编写
pom.xml
文件,增加依赖<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>xyz.rtx3090</groupId> <artifactId>002-link-consumer</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!--spring 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.16.RELEASE</version> </dependency> <!--dubbo 依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 依赖服务提供者 --> <dependency> <groupId>xyz.rtx3090</groupId> <artifactId>001-link-userService-provider</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <!-- 规定我的项目 JDK 版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> <resources> <!-- 解决 Maven 动态资源过滤问题 --> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build> </project>
-
新建包
xyz.rtx3090.dubbo.web
,并在其下新建类UserController
package xyz.rtx3090.dubbo.web; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import xyz.rtx3090.dubbo.model.User; import xyz.rtx3090.dubbo.service.UserService; @Controller public class UserController { @Autowired private UserService userService; @RequestMapping(value = "/user") public String userDetail(Model model,Integer id) {User user = userService.queryUserById(id); model.addAttribute("user",user); return "userDetail"; } }
-
在
webapp
目录下新建userDetail.jsp
页面<%-- Created by IntelliJ IDEA. User: bernardo Date: 2021/8/16 Time: 03:16 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title> 用户详情 </title> </head> <body> <h1> 用户详情 </h1> <div> 用户标识: ${user.getId()}</div> <div> 用户名称:${user.getName()}</div> </body> </html>
-
在
resources
目录下,新建dubbo-consumer.xml
配置文件<?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" 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"> <!-- 申明服务消费者的名称——保障唯一性 --> <dubbo:application name="002-link-consumer"/> <!-- 援用近程服务接口:id——近程服务接口对象的名称 interface——调用近程接口的全限定类名称 url——拜访服务接口的地址 registry——不应用注册核心,值为:N/A--> <dubbo:reference id="userService" interface="xyz.rtx3090.dubbo.service.UserService" url="dubbo://localhost:20880" registry="N/A"/> </beans>
-
在
resources
目录下,新建application.xml
spring 外围配置文件<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 扫描组件 --> <context:component-scan base-package="xyz.rtx3090.dubbo.web"/> <!-- 配置注解驱动 --> <mvc:annotation-driven/> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
-
批改
web.xml
配置文件<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 注册 DispatcherServlet 地方调度器 --> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:application.xml,classpath:dubbo-consumer.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
配置
001-link-userService-provider
我的项目的 Tomcat 服务器,重点批改Http port
端口和JMX port
端口 -
配置
002-link-consumer
我的项目的 Tomcat 服务器 -
先启动
001-link-userService-provider
我的项目的 Tomcat 服务器,再启动002-link-consumer
我的项目的 Tomcat 服务器,并在浏览器地址栏中输出http://localhost:8080/user?001
,查看页面后果
Dubbo 服务化最佳实际
分包
倡议将服务接口、服务模型等均放在公共包中
粒度
- 服务接口尽可能大粒度,每个服务办法应代表一个性能,而不是某性能的一个步骤
- 服务接口倡议以业务场景为单位划分,并对相近业务做形象,避免接口数量暴涨
- 不倡议应用过于形象的通用接口,如
Map query(Map)
,这样的接口没有明确语义,会给前期保护带来不便
版本
每个接口都应定义版本号,辨别同一个接口的不同实现
如:<dubbo:service interface="com.xxx.XxxService" version="1.0"
Dubbo 罕用标签
Dubbo 中罕用标签分为三个类别:
- 共用标签
- 服务提供者标签
- 服务消费者标签
共用标签
-
配置利用信息
<dubbo:appliation name="服务的名称"/>
-
配置注册核心
<dubbo:registry address="ip:port" protocol="协定"/>
服务提供者标签
-
配置裸露的服务
<dubbo:service interface="服务接口名" ref="服务实现对象 bean"/>
服务消费者标签
-
配置服务消费者援用近程服务
<dubbo:reference id="服务援用 bean 的 id" interface="服务接口名"/>
Dubbo 直连 - 革新案例
为了解决 Dubbo 直连实现
中的问题,咱们须要引入一个 接口工程
,将 bean 实体类和公共接口放入到这个 接口工程
-
新建一般 maven 工程(不带 web 模版)
003-link-interface
,最终我的项目目录构造如图所示: -
创立
readme.md
文件,书写我的项目思路link-interface 是一个 maven java 工程 dubbo 官网举荐应用的一个模式,将实体 bean 和业务接口寄存到接口工程中
-
批改
pom.xml
配置文件,去除不须要的内容<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>xyz.rtx3090</groupId> <artifactId>003-link-interface</artifactId> <version>1.0-SNAPSHOT</version> </project>
-
在
java
目录下创立包xyz.rtx3090.model
,并新建User
实体类package xyz.rtx3090.model; import java.io.Serializable; public class User implements Serializable { private Integer id; private String username; //setter and getter public Integer getId() {return id;} public void setId(Integer id) {this.id = id;} public String getUsername() {return username;} public void setUsername(String username) {this.username = username;} }
-
在
java
目录下创立包xyz.rtx3090.service
,并新建UserService
接口package xyz.rtx3090.service; import xyz.rtx3090.model.User; public interface UserService { /** * 通过 id 查问用户信息 * @param id 用户 id 号 * @return 用户对象 */ User queryUserById(Integer id); /** * 查问用户总人数 * @return 用户总人数 */ Integer queryAllUserCount();}
-
新建 maven web 工程
004-link-userService-provider
,最终我的项目目录构造如图所示: -
批改
pom.xml
文件,增加所须要的依赖<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>xyz.rtx3090</groupId> <artifactId>004-link-userService-provider</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!--spring 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.16.RELEASE</version> </dependency> <!--dubbo 依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 接口工程 --> <dependency> <groupId>xyz.rtx3090</groupId> <artifactId>003-link-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <!-- 规定我的项目 JDK 版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
-
在
java
目录下新建包xyz.rtx3090.service.impl
,并在其包下新建UserServiceImpl
实现类package xyz.rtx3090.service.impl; import xyz.rtx3090.model.User; import xyz.rtx3090.service.UserService; public class UserServiceImpl implements UserService { @Override public User queryUserById(Integer id) {User user = new User(); user.setId(id); user.setUsername("Jason"); return user; } @Override public Integer queryAllUserCount() {return 52;} }
-
在
resources
目录下新建dubbo-userService-provider.xml
配置文件<?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" 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"> <!-- 申明 dubbo 服务提供者名称——保障唯一性 --> <dubbo:application name="004-link-userService-provider"/> <!-- 设置 dubbo 应用协定和端口号 name:协定名称 port:端口号 --> <dubbo:protocol name="dubbo" port="20880"/> <!-- 裸露服务接口 --> <dubbo:service interface="xyz.rtx3090.service.UserService" ref="userServiceImpl" registry="N/A"/> <!-- 加载业务接口的实现类到 spring 容器中 --> <bean id="userServiceImpl" class="xyz.rtx3090.service.impl.UserServiceImpl"/> </beans>
-
批改
web.xml
配置文件,注册监听器<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 注册监听器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo-userService-provider.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
-
新建 maven web 工程
005-link-consumer
,最终我的项目目录构造如图所示: -
批改
pom.xml
文件,增加所须要的依赖<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>xyz.rtx3090</groupId> <artifactId>005-link-consumer</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <!--spring 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.16.RELEASE</version> </dependency> <!--dubbok 依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 接口工程 --> <dependency> <groupId>xyz.rtx3090</groupId> <artifactId>003-link-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <!-- 规定我的项目 JDK 版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
-
在
java
目录下新建包xyz.rtx3090.web
,并在其包下新建UserController
类package xyz.rtx3090.web; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import xyz.rtx3090.model.User; import xyz.rtx3090.service.UserService; import javax.annotation.Resource; @Controller public class UserController { @Resource private UserService userService; @RequestMapping(value = "/userDetail") public String userDetail(Model model, Integer id) { // 依据用户标示获取用户详情 User user = userService.queryUserById(id); // 获取用户总人数 Integer count = userService.queryAllUserCount(); model.addAttribute("user",user); model.addAttribute("allUserCount",count); return "userDetail"; } }
-
在
webapp
目录下新建userDetail.jsp
页面<%-- Created by IntelliJ IDEA. User: bernardo Date: 2021/8/17 Time: 12:52 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title> 用户详情 </title> </head> <body> <h2> 用户详情页面 </h2> <div> 用户标示:${user.id}</div> <div> 用户姓名:${user.username}</div> <div> 用户人数:${allUserCount}</div> </body> </html>
-
在
resources
目录下新建dubbo-consumer.xml
配置文件<?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" 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"> <!-- 申明服务消费者名称——保障唯一性 --> <dubbo:application name="005-link-consumer"/> <!-- 援用近程接口服务 --> <dubbo:reference id="userService" interface="xyz.rtx3090.service.UserService" url="dubbo://localhost:20880" registry="N/A"/> </beans>
-
在
resources
目录下新建applicationContext.xml
配置文件<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 扫描组件 --> <context:component-scan base-package="xyz.rtx3090.web"/> <!-- 配置注解驱动 --> <mvc:annotation-driven/> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
-
批改
web.xml
配置文件,注册地方调度器<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 注册地方调度器 --> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml,classpath:dubbo-consumer.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
配置并启动
004-link-userService-provider
的 tomcat 服务器 -
配置并启动
005-link-consumer
的 tomcat 服务器 -
在浏览器地址栏输出
http://localhost:8080/005/userDetail?id=1
,查看测试后果
注册核心
概述
对于服务提供方它须要公布服务,而且因为利用零碎的复杂性——服务的数量、类型也一直收缩;
对于服务消费者,它最关怀如何获取到它所需的服务,而面对简单的利用零碎,须要治理大量的服务调用。
而且,对于服务提供方和服务生产方来说,他们还有可能兼具这两种角色,即须要提供服务,又须要生产服务。
通过将服务对立治理起来,能够无效地优化外部利用对服务公布 / 应用的流程和治理。
服务注册核心能够通过特定协定来实现服务对外的对立,Dubbo 提供的注册核心有如下几种类型可供选择:
Multicast
注册核心:组播形式Redis
注册核心:应用 Redis 作为注册核心Simple
注册核心:就是一个 dubbo 服务,作为注册核心,提供查找服务的性能Zookeeper
注册核心:应用 Zookeeper 作为注册核心(举荐)
注册核心工作形式
Zookeeper 注册核心
Zookeeper 是一个高性能的、开源的分布式应用程序协调服务,简称 ZK
。Zookeeper 直译为 动物园管理员
,能够了解为 windows 中的资源管理器或者注册表。他是一个树形构造,这种树形构造和规范文件系统类似。Zookeeper 数中的每个节点能够领有子节点,每个节点示意一个惟一服务资源,Zookeeper 运行须要 Java 环境。
下载
留神咱们这里要下载
3.5.6
版本的,不然可能会呈现不兼容的状况
装置
将下载的 apache-zookeeper-3.5.6-bin.tar.gz
文件,解压到指定目录地位即可
tar -zxvf apache-zookeeper-3.5.9-bin.tar.gz -C /usr/local/
配置文件
配置文件详解
tickTime
:间接翻译为心跳工夫,单位毫秒。Zookeeper 服务器之间或客户端与服务器之间维持心跳的工夫距离,也就是每个 tickTime 工夫就会发送一个心跳,表明存活状态dataDir
:数据目录,能够是任意目录。存错 zookeeper 的快照文件、pid 文件,默认为/tmp/zookeeper
,倡议在zookeeper
装置目录下创立data
目录,将dataDir
配置改为/usr/local/zookeeper-3.5.9/data
自定义配置文件内容
- 复制
conf/zoo_sample.cfg
文件到同级目录中改名为zoo.cfg
- 在
apache-zookeeper-3.5.9-bin
根目录下创立data
文件夹 - 批改配置文件
conf/zoo.cfg
中的dataDir=/Users/bernardo/JavaDoc/apache-zookeeper-3.5.9-bin/data
(即上述创立的文件夹门路) - 批改配置文件
conf/zoo.cfg
,在clientPort=2181
上面退出admin.serverPort=8888
conf/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=/Users/bernardo/JavaDoc/zookeeper-3.5.9/data
# the port at which the clients will connect
clientPort=2181
admin.serverPort=8888
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
启动
切换到 bin
目录下,执行命令./zkServer.sh start
敞开
切换到 bin
目录下,执行命令./zkServer.sh stop
Dubbo 案例革新—本地应用 zookeeper
-
新建一般 maven java 子工程
001-zk-interface
,最终我的项目目录如图所示: -
在
java
目录下新建包xyz.rtx3090.model
,并在其下新建User
实体类package xyz.rtx3090.model; import java.io.Serializable; public class User implements Serializable { private Integer id; private String username; //setter and getter public Integer getId() {return id;} public void setId(Integer id) {this.id = id;} public String getUsername() {return username;} public void setUsername(String username) {this.username = username;} }
-
在
java
目录下新建包xyz.rtx3090.service
,并在其下新建UserService
接口package xyz.rtx3090.service; import xyz.rtx3090.model.User; public interface UserService { /** * 依据用户 id 查问用户信息 * @param id 用户 id * @return 用户信息 */ User queryUserById(Integer id); }
-
新建 maven web 子工程
002-zk-userService-provider
,最终目录构造如图所示: -
批改
pom.xml
文件,增加所需的依赖<dependencies> <!--spring 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.16.RELEASE</version> </dependency> <!--dubbo 依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 接口工程依赖 --> <dependency> <groupId>xyz.rtx3090</groupId> <artifactId>001-zk-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- 注册核心依赖 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.1.0</version> </dependency> </dependencies> <build> <plugins> <!-- 规定我的项目 JDK 版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
-
在
java
目录下新建包xyz.rtx3090.service.impl
,并在其下新建UserServiceImpl
类package xyz.rtx3090.service.impl; import xyz.rtx3090.model.User; import xyz.rtx3090.service.UserService; public class UserServiceImpl implements UserService { /** * 依据用户 id 获取用户信息 * @param id 用户 id * @return 用户对象 */ @Override public User queryUserById(Integer id) {User user = new User(); user.setId(id); user.setUsername("Jason" + id); return user; } }
-
在
resources
目录下创立dubbo-userService-provider.xml
配置文件<?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" 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"> <!-- 申明 dubbo 服务提供者名称——保障唯一性 --> <dubbo:application name="002-zk-userService-provider"/> <!-- 注册核心 zookeeper--> <dubbo:registry address="zookeeper://localhost:2181"/> <!-- 设置 dubbo 应用的协定和端口号 --> <dubbo:protocol name="dubbo" port="20880"/> <!-- 裸露服务接口 --> <dubbo:service interface="xyz.rtx3090.service.UserService" ref="userServiceImpl"/> <!-- 加载业务接口的实现类到 spring 容器中 --> <bean id="userServiceImpl" class="xyz.rtx3090.service.impl.UserServiceImpl"/> </beans>
-
批改
web.xml
配置文件,注册监听器<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 注册监听器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo-userService-provider.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
-
新建 maven web 子工程
003-zk-consumer
,最终目录构造如图所示: -
批改
pom.xml
配置文件,增加所需的依赖<dependencies> <!--spring 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.16.RELEASE</version> </dependency> <!--dubbo 依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 接口工程依赖 --> <dependency> <groupId>xyz.rtx3090</groupId> <artifactId>001-zk-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- 注册核心依赖 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.1.0</version> </dependency> </dependencies> <build> <plugins> <!-- 规定我的项目 JDK 版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
-
在
java
目录下新建包xyz.rtx3090.web
,并在其下新建UserController
类package xyz.rtx3090.web; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import xyz.rtx3090.model.User; import xyz.rtx3090.service.UserService; import javax.annotation.Resource; @Controller public class UserController { @Resource private UserService userService; @RequestMapping(value = "/userDetail") public String userDetail(Model model, Integer id) {User user = userService.queryUserById(id); model.addAttribute("user",user); return "userDetail"; } }
-
在
webapp
目录下新建userDetail.jsp
页面<%-- Created by IntelliJ IDEA. User: bernardo Date: 2021/8/18 Time: 15:04 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title> 用户信息 </title> </head> <body> <h2> 用户详情信息页面 </h2> <div> 用户编号:${user.id}</div> <div> 用户姓名:${user.username}</div> </body> </html>
-
在
resources
目录下新建dubbo-consumer.xml
配置文件<?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" 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"> <!-- 申明服务消费者名称——保障唯一性 --> <dubbo:application name="003-zk-consumer"/> <!-- 注册核心 zookeeper--> <dubbo:registry address="zookeeper://localhost:2181"/> <!-- 援用近程接口服务 --> <dubbo:reference id="userServiceImpl" interface="xyz.rtx3090.service.UserService"/> </beans>
-
在
resources
目录下新建applicationContext.xml
spring 配置文件<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 扫描组件 --> <context:component-scan base-package="xyz.rtx3090.web"/> <!-- 配置注解驱动 --> <mvc:annotation-driven/> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
-
批改
web.xml
配置文件<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 配置地方调度器 --> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml,classpath:dubbo-consumer.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
切换到
zookeeper-3.5.6/bin/
目录,执行./zkServer.sh start
来启动 zookeeper 注册核心 -
配置并启动
002-zk-userService-provider
我的项目的 tomcat 服务器 -
配置并启动
003-zk-consumer
我的项目的 tomcat 服务器 -
在浏览器地址栏输出
http://localhost:8080/003/userDetail?id=1
,查看页面测试后果
Dubbo 案例革新—近程主机应用 zookeeper
在
Dubbo 案例革新—本地应用 zookeeper
的代码根底上进行批改
- 在近程主机上 下载 、 配置 并启动 zookeeper,步骤和在本地主机上的一样(记得凋谢端口
2181
和8888
) -
批改
002-zk-userService-provider
的dubbo-userService-provider
配置文件<!-- 批改注册核心 zookeeper,将 localhost 换成近程主机的 ip--> <dubbo:registry address="zookeeper://1.117.144.59:2181"/>
-
批改
003-zk-consumer
的dubbo-consumer
配置文件<!-- 批改注册核心 zookeeper,将 localhost 换成近程主机的 ip--> <dubbo:registry address="zookeeper://1.117.144.59:2181"/>
-
配置并启动
002
、003
我的项目的 tomcat 服务器,在浏览器地址栏输出http://localhost:8080/003/userDetail?id=2
,查看页面测试后果
Dubbo 配置
敞开查看
dubbo 缺省会在启动时查看依赖的服务是否可用,不可用时会抛出异样,阻止 Spring 初始化实现,以便上线时能及时发现问题,默认 check=true
。通过check=false
敞开查看。比方测试时,有些服务不关怀,或者呈现了循环依赖,必须有一方先启动。
-
例一:敞开某人服务的启动时查看
<dubbo:reference interface="xyz.rtx3090.BarService" check="false"/>
-
例二:敞开注册核心启动时查看
<dubbo:registry check="false"/>
默认启动服务时,查看核心存在并已运行,注册核心不启动会报错
重试次数
消费者拜访提供者,如果拜访失败,则切换重试拜访其余服务器,但重试会带来更长提早。拜访工夫变长,用户的体验较差。屡次从新拜访服务器有可能拜访胜利。可通过 retries="2"
来设置重试次数(不含第一次)
<dubbo:service retries="2"/>
<dubbo:reference retries="2"/>
超时工夫
因为网络或服务端不牢靠,会导致调用呈现一种不确定的中间状态(超时)。为了防止超时导致客户端资源(线程)挂起耗尽,必须设置超时工夫。
通过设置 timeout
来调整近程服务超时工夫(毫秒)
-
调整生产端服务超时工夫
<dubbo:reference interface="xyz.rtx3090.BerServicee" timeout="2000"/>
-
调整服务端超时工夫
<dubbo:server interface="xyz.rtx3090.BarService" timeout="2000"/>
版本号
每个接口都应定义版本号,为后续不兼容降级提供可能。当一个接口有不同的实现,我的项目晚期应用的一个实现类,之后创立接口的新实现类。辨别不同接口实现应用 version,特地是我的项目须要把晚期接口的实现全副换位新的实现类,也须要实现 version。
能够用版本号从晚期实现适度到欣的接口实现,版本号不同的服务相互间不援用。
能够依照以下的步骤进行版本迁徙:
- 在低压力时间段,先降级一半提供者为新版本
- 再将所有消费者降级为新版本
- 而后将剩下的一半提供者降级为新版本
Dubbo 案例革新 - 多版本 + 近程 zookeeper
有时候咱们在降级新版本的时候同样须要兼顾旧版本,这个时候咱们就须要【多版本】的计划了
-
新建一般 maven java 工程
009-zk-multi-interface
,最终我的项目目录构造如图所示: -
在 java 目录下新建包
xyz.rtx3090.model
,并在其下新建User
实体类package xyz.rtx3090.model; import java.io.Serializable; public class User implements Serializable { private Integer id; private String username; //setter and getter public Integer getId() {return id;} public void setId(Integer id) {this.id = id;} public String getUsername() {return username;} public void setUsername(String username) {this.username = username;} }
-
在 java 目录下新建包
xyz.rtx3090.service
,并在其下新建UserService
类package xyz.rtx3090.service; import xyz.rtx3090.model.User; public interface UserService { /** * 依据用户 id 获取用户音讯 * @param id 用户 id * @return 用户对象 */ User queryUserById(Integer id); }
-
新建 maven web 工程,最终我的项目构造如图所示:
-
批改
pom.xml
文件,增加所需依赖<dependencies> <!--spring 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.16.RELEASE</version> </dependency> <!--dubbo 依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 接口工程 --> <dependency> <groupId>xyz.rtx3090</groupId> <artifactId>009-zk-multi-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- 注册核心依赖 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.1.0</version> </dependency> </dependencies> <build> <plugins> <!-- 规定我的项目 JDK 版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
-
在 java 目录下新建包
xyz.rtx3090.service.impl
包,并在其下新建UserServiceImpl
类和UserServiceImpl2
类package xyz.rtx3090.service.impl; import xyz.rtx3090.model.User; import xyz.rtx3090.service.UserService; public class UserServiceImpl implements UserService { @Override public User queryUserById(Integer id) {User user = new User(); user.setId(id); user.setUsername("Jason" + id); return user; } }
package xyz.rtx3090.service.impl; import xyz.rtx3090.model.User; import xyz.rtx3090.service.UserService; public class UserServiceImpl2 implements UserService { @Override public User queryUserById(Integer id) {User user = new User(); user.setId(id); user.setUsername("Bernardo" + id); return user; } }
-
在 resources 目录下新建
dubbo-userService-multi-provider.xml
配置文件<?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:dubbbo="http://dubbo.apache.org/schema/dubbo" 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"> <!-- 申明 dubbo 服务提供者名称:保障唯一性 --> <dubbo:application name="010-zk-userService-multi-provider"/> <!-- 申明 dubbo 协定和端口号 --> <dubbbo:protocol name="dubbo" port="20880"/> <!-- 申明注册核心 --> <dubbo:registry address="zookeeper://1.117.144.59:2181"/> <!-- 多版本,裸露服务接口(不论是不是多版本,最好都提供版本号)--> <dubbo:service interface="xyz.rtx3090.service.UserService" ref="userService1" version="1.0.0"/> <dubbo:service interface="xyz.rtx3090.service.UserService" ref="userService2" version="2.0.0"/> <bean id="userService1" class="xyz.rtx3090.service.impl.UserServiceImpl"/> <bean id="userService2" class="xyz.rtx3090.service.impl.UserServiceImpl2"/> </beans>
-
批改
web.xml
配置文件<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 注册监听器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo-userService-multi-provider.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
-
新建 maven web 工程
011-zk-multi-consumer
,最终我的项目目录构造如图所示: -
批改
pom.xml
配置文件,增加我的项目所需依赖<dependencies> <!--spring 依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.16.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.16.RELEASE</version> </dependency> <!--dubbo 依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.6.2</version> </dependency> <!-- 接口工程 --> <dependency> <groupId>xyz.rtx3090</groupId> <artifactId>009-zk-multi-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!-- 注册核心依赖 --> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.1.0</version> </dependency> </dependencies> <build> <plugins> <!-- 规定我的项目 JDK 版本 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
-
在 java 目录下新建包
xyz.rtx3090.web
,并在其下新建类UserController
package xyz.rtx3090.web; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import xyz.rtx3090.model.User; import xyz.rtx3090.service.UserService; @Controller public class UserController { @Autowired @Qualifier("userServiceImpl") // 这里的 byName 主动注入是根据 `dubbo-multi-consumer` 配置文件中的 `dubbo:reference` 标签属性 `id` private UserService userServiceImpl; @Autowired @Qualifier("userServiceImpl2") private UserService userServiceImpl2; @RequestMapping(value = "/userDetail") public String userDetail(Model model, Integer id) {User user1 = userServiceImpl.queryUserById(id); User user2 = userServiceImpl2.queryUserById(id); model.addAttribute("user1",user1); model.addAttribute("user2",user2); return "userDetail"; } }
-
在 resources 目录下新建配置文件
dubbo-multi-consumer.xml
<?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" 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"> <!-- 申明 dubbo 服务消费者名称:保障服务名称的唯一性 --> <dubbo:application name="011-zk-multi-consumer"/> <!-- 指定注册核心 --> <dubbo:registry address="zookeeper://1.117.144.59:2181"/> <!-- 援用近程接口服务 --> <dubbo:reference id="userServiceImpl" interface="xyz.rtx3090.service.UserService" version="1.0.0"/> <dubbo:reference id="userServiceImpl2" interface="xyz.rtx3090.service.UserService" version="2.0.0"/> </beans>
-
在 resources 目录下新建配置文件
applicationContext.xml
<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 组件扫描器 --> <context:component-scan base-package="xyz.rtx3090.web"/> <!-- 配置注解驱动 --> <mvc:annotation-driven/> <!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
-
批改
web.xml
配置文件<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!-- 注册地方调度器 --> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dubbo-multi-consumer.xml,classpath:applicationContext.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
在 webapp 目录下新建
userDetail.jsp
页面<%-- Created by IntelliJ IDEA. User: bernardo Date: 2021/8/19 Time: 14:51 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title> 用户信息页面 </title> </head> <body> <h2> 用户一 </h2> <div> 用户编号:${user1.id}</div> <div> 用户姓名:${user1.username}</div> <h2> 用户二 </h2> <div> 用户编号:${user2.id}</div> <div> 用户姓名:${user2.username}</div> </body> </html>
- 启动近程主机的 zookeeper
-
配置并启动我的项目
010-zk-userService-multi-provider
的 tomcat 服务器(留神批改端口号,防止两个 tomcat 服务器抵触) -
配置比启动我的项目
011-zk-multi-consumer
的 tomcat 服务器 - 在浏览器地址栏中输出
http://localhost:8080/011/userDetail?id=1
,查看页面测试后果
监控核心
什么是监控核心
dubbo 的应用其实只须要有注册核心、消费者、提供者三个就能够应用了,然而并不能看到有哪些消费者和提供者。为了更好的调试、发现问题、解决问题,因而引入 dubbo-admin
,通过dubbo-admin
能够对消费者和提供者进行治理,能够在 dubbo 援用部署做动静的调整、服务治理。
-
dubbo-admin
图形化服务治理页面,装置时须要执行注册核心地址,即可从注册核心中获取到所有的提供这者、消费者进行配置管理
-
dubbo-monitor-simple
简略的监控核心
应用监控核心
-
进入
https://github.com/apache/dubbo-admin
下载dubbo-admin
工程 - 应用 idea 关上下载的
dubbo-admin
工程 -
进入
dubbo-admin-develop/dubbo-admin-server
目录,关上pom.xml
文件,增加maven-antrun-plugin
的grouid
为org.apache.maven.plugins
,并确定其余内容没有报红<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.8</version> <executions> <execution> <phase>verify</phase> <configuration> <tasks> <copy file="target/dubbo-admin-server-${project.version}.jar" tofile="../dubbo-admin-distribution/target/dubbo-admin-${project.version}.jar"/> </tasks> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin>
-
进入
dubbo-admin-develop/dubbo-admin-server/srcd/main/resources
目录,关上application.properties
配置文件,设置一些 ip 和端口信息# ip 地址和端口号改为本人 zookeeper 设置 ip 端口 admin.registry.address=zookeeper://127.0.0.1:2181 admin.config-center=zookeeper://127.0.0.1:2181 admin.metadata-report.address=zookeeper://127.0.0.1:2181 # 前面在浏览器登录 admin 零碎的账号密码 admin.root.user.name=root admin.root.user.password=root # 新增设置端口号为 7001(默认为 8080,与 tomcat 抵触)server.port=7001
-
点击右侧的 maven 工具,进入
dubbo-admin(root)/Lifecyde
先点击clean
选项,而后点击package
抉择构建 Jar 包 - 启动
zookeeper
和dubbo
我的项目 -
等 Jar 包构建实现和下面启动结束,进入
dubbo-admin-develop/dubbo-admin-distribution/target
目录,在此目录下关上终端,执行java -jar dubbo-admin-0.3.0.jar
命令 -
在浏览器地址栏输出
http://localhost:7001
(7001 是下面我本人设置的端口号),即可对 dubbo 我的项目进行监控