Dubbo

本文详细介绍了Dubbo RPC的基本原理、dubbo框架的使用,包括点对点直连、Zookeeper注册中心的安装与配置,以及服务消费者和服务提供者的完整例子。涵盖了服务暴露、负载均衡策略和监控中心的概述。
摘要由CSDN通过智能技术生成

Dubbo

1、RPC 基础知识

1.1、软件架构

单一应用架构

单一应用架构:就是之前练习的系统,将所有的功能都部署在一起,只需一个应用

当网站流量很小时,应用规模小时,只需一个应用,将所有功能都部署在一起,以减少部署服务器数量和成本

适合小型系统,小型网站,或者企业的内部系统,用户较少,请求量不 大,对请求的处理时间没有太高的要求

缺点: 1、性能扩展比较困难 2、不利于多人同时开发 3、不利于升级维护 4、整个系统的空间占用比较大

在这里插入图片描述

分布式服务架构

将核心业务抽取出来,作为独立的服务

在这里插入图片描述

1.2、分布式系统

分布式系统中的计算机可以使用不同的操作系统,可以运行不同应用程序提供服务,将 服务分散部署到多个计算机服务器上

1.2.1、RPC

RPC 【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,是一种技 术思想,而不是规范

它允许程序调用另一个地址空间(网络的另一台机器上)的过程或函 数,而不用开发人员显式编码这个调用的细节

RPC 的特点

  1. 简单:使用简单,建立分布式应用更容易
  2. 高效:调用过程看起来十分清晰,效率高
  3. 通用:进程间通讯的方式,有通用的规则

rpc 通讯是基于 tcp 或 udp 议

序列化方式(xml/json/二进制)

1.2.2、RPC 基本原理

在这里插入图片描述

2、dubbo 框架

一般服务器与服务器之间使用的是长连接方式,用户与服务器之间使用短连接方式访问

面向接口代理:

调用接口的方法,在 A 服务器调用 B 服务器的方法,由 dubbo 实现对 B 的 调用,无需关心实现的细节,就像 MyBatis 访问 Dao 的接口,可以操作数据库一样。不用关心 Dao 接口方法的实现

动态代理对象

2.1、dubbo 支持的协议

支持多种协议:dubbo , hessian , rmi , http, webservice , thrift , memcached , redis。 dubbo 官方推荐使用 dubbo 协议

dubbo 协议默认端口 20880

dubbo 协议采用单一长连接和异步通讯,适用于小数据量大并发的服务调用,不适合于大数据量的服务(比如文件、视频等)

一般服务器与服务器之间使用的是长连接方式,用户与服务器之间使用短连接方式访问

使用 dubbo 协议,spring 配置文件加入:

<dubbo:protocol name="dubbo" port="20880"/>

2.2、基本架构

服务提供者(Provider):暴露服务的服务提供方,服务提供者在启动时,向注册中心注 册自己提供的服务

服务消费者(Consumer): 调用远程服务的服务消费方,服务消费者在启动时,向注册 中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一 台提供者进行调用,如果调用失败,再选另一台调用

注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册 中心将基于长连接推送变更数据给消费者

监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心(可以没有)

调用关系说明:

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

2.3、使用 Dubbo 的第一个项目

先写的简单一点,使用 点对点的直连方式

点对点的直连项目:消费者直接访问服务提供者,没有注册中心

消费者必须指定服务提供者的访问地址(url),消费者直接通过 url 地址访问固定的服务提供者,这个 url 地址是不变的

2.3.1、服务提供者

步骤:

  1. 新建 maven web 工程

  2. 创建实体类,保存在网络中传输的数据

    注意此类需要实现序列化接口,否则后面启动项目会报错

  3. 定义服务接口和实现类:UserService

  4. 定义 spring 配置文件

    1. 声明 Dubbo 服务名称:保证唯一
    2. 声明 Dubbo 使用的协议和端口号
    3. 暴露服务接口,使用直连方式
    4. 声明服务接口的实现类对象
  5. 测试配置文件是否有效

  6. 添加监听器(创建spring容器对象)

  7. 将项目打包成 jar 包

    1. 消费者怎么知道提供者暴露了哪些接口呢?

      这里需要将提供者的工程打包成一个 jar 包,并放入本地仓库,作为消费者 maven 的一个依赖

    2. 将打包方式改为 jar ,然后进行打包,放入本地仓库


      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nu0MilaN-1649580916259)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220221115109975.png)]

    3. 然后再将打包方式改回 war

    4. 在消费者项目中,引入此依赖

      <!--依赖服务提供者-->
      <dependency>
        <groupId>com.afei</groupId>
        <artifactId>001_test</artifactId>
        <version>1.0-SNAPSHOT</version>
      </dependency>
      
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>com.afei</groupId>
  <artifactId>001_test</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <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>
    <!-- lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.12</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
      <plugins>
          <!-- 插件 Tomcat7 -->
          <plugin>
              <groupId>org.apache.tomcat.maven</groupId>
              <artifactId>tomcat7-maven-plugin</artifactId>
              <version>2.1</version>
              <configuration>
                  <port>8080</port> <!-- 端口 -->
                  <path>/</path> <!-- 上下路径 -->
                  <uriEncoding>UTF-8</uriEncoding> <!-- 针对 GET 方式乱码处理 -->
              </configuration>
          </plugin>
      </plugins>
  </build>

</project>
实体类

自定义类,使用 idea 自动生成序列化版本号

在类名上 Alt + Enter ,生成序列化版本号

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {
    private Integer id;
    private String username;
    private Integer age;
}
service 接口及实现类
public interface UserService {
    User queryUserById(Integer id);
}
public class UserServiceImpl implements UserService {
    @Override
    public User queryUserById(Integer id) {
        User user = new User(1001, "lisi", 20);
        return user;
    }
}
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://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!-- dubbo 提供者的配置文件-->
    <!--声明服务的名称,自定义名字表示当前服务提供者
        name:自定义服务名称,一般使用项目名称,使用唯一值
              服务名称是 Dubbo 内部使用标识服务的
    -->
    <dubbo:application name="001-link-userservice-provider"/>
    <!--访问服务协议的名称、端口
            name:指定协议名称,官方推荐使用 dubbo 协议
            port:指定协议端口号,默认20880
    -->
    <dubbo:protocol name="dubbo" port="20880"/>
    <!--暴露服务接口
            interface:接口全限定名称
            ref:指定接口实现类的bean的id
            registry:指定使用注册中心。这里是点对点直连方式,不使用注册中心,赋值为N/A:不使用注册中心
    -->
    <dubbo:service interface="com.service.UserService" ref="userServiceImpl" registry="N/A"/>
    <!--声明服务接口的实现类对象,真正提供接口的功能实现-->
    <bean id="userServiceImpl" class="com.service.impl.UserServiceImpl"/>
</beans>

第二、三步可以合并为一个标签

<dubbo:service interface="com.service.UserService"
               ref="userServiceImpl"
               protocol="dubbo"
               registry="N/A"/>

写完配置文件可以进行简单测试,如果没有报错,验证读取是否成功、配置是否有效

public static void main(String[] args) {
    //创建spring容器对象
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("dubbo-userservice-provider.xml");
    ctx.start();
}
web.xml
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <!--声明监听器
        1、默认监听器:创建容器对象是,读取配置文件:/WEB_INF/applicationContext.xml
        2、自定义日期使用配置文件的路径:使用 context-param 标签
-->
  <!--自定义spring容器使用的配置文件路径
      context-param 叫做上下文路径,给监听器提供参数的
  -->
  <context-param>
    <!-- contextConfigLocation:固定名称,表示自定义spring配置文件路径 -->
    <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>

2.3.2、服务消费者

步骤:

  1. 新建 maven 项目
  2. 定义 spring 配置文件
    1. 声明服务的名称
    2. 声明要使用的服务,引用服务提供者
  3. 定义使用者类,调用服务提供者的功能吗,这是一个远程调用

消费者怎么知道提供者暴露了哪些接口呢?

这里需要将提供者的工程打包成一个 jar 包,然后放入本地仓库,作为消费者 maven 的一个依赖

pom.xml
  <!--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>com.afei</groupId>
    <artifactId>001_test</artifactId>
    <version>1.0-SNAPSHOT</version>
  </dependency>
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 消费者的配置文件-->
    <!--声明服务的名称(声明服务的操作是一样的)-->
    <!--声明服务的名称,自定义名字表示当前服务提供者
        name:自定义服务名称,一般使用项目名称,使用唯一值
              服务名称是 Dubbo 内部使用标识服务的
    -->
    <dubbo:application name="002-link-consumer"/>
    <!--引用远程服务接口
            interface:dubbo服务接口全限定名称
            id:dubbo创建的代理对象的id,使用这个id访问代理对象
            url:点对点方式中,访问远程服务的地址
                  dubbo://localhost:20880
    -->
    <dubbo:reference interface="com.service.UserService"
                     id="remoteUserService"
                     url="dubbo://localhost:20880" registry="N/A"/>

    <bean id="invokeService" class="com.service.InvokeService">
        <property name="service" ref="remoteUserService"/>
    </bean>
</beans>
定义使用者类
public class MyClient {
    public static void main(String[] args) {
        //创建 spring 容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("dubbo-consumer.xml");
        //从容器中获取远程的代理对象
        UserService service = (UserService) ctx.getBean("remoteUserService");
        System.out.println(service);    //com.alibaba.dubbo.common.bytecode.proxy0@776aec5c 说明是生成的代理对象
        //通过代理对象执行方法的调用,就像调用自己的方法一样
        User user = service.queryUserById(1001);
        System.out.println("通过代理对象执行方法的调用结果" + user);
    }
}

2.3.3、运行项目

直接输出代理对象,执行方法调用

需要启动服务提供者的 Tomcat 服务,然后执行 消费者中使用者类的 main 方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lMgwNpvb-1649580916262)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220221131033430.png)]

当执行 service.queryUserById(1001);,方法传入参数之后,进行序列化,传递到 001提供者 项目中

该项目执行得到 user 对象,然后经过序列化传递回 002 消费者项目

002经过反序列化得到结果 user 对象,赋值给 User user

代理对象作为业务类的属性

(也可以创建 springmvc 配置文件,使用注解方式,定义controller类,来调用业务类对象执行方法)

定义业务类

@Setter
public class InvokeService {
    private UserService service;
    public void printService(){
        User user = service.queryUserById(1001);
        System.out.println("通过代理对象执行方法的调用结果" + user);
    }

配置文件中声明 bean 对象

<bean id="invokeService" class="com.service.InvokeService">
    <property name="service" ref="remoteUserService"/>
</bean>

使用者类创建业务类对象,执行方法

public class MyClient {
    public static void main(String[] args) {
        //创建 spring 容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("dubbo-consumer.xml");
        //从容器中获取 Service 对象
        InvokeService service = (InvokeService) ctx.getBean("invokeService");
        service.printService();
    }
}

需要启动服务提供者项目的 Tomcat 服务,然后执行消费者项目中使用者类的 main 方法

2.4、使用接口作为独立项目

假如此时有多个功能提供者,消费者需要使用查看用户信息、获取天气状况、查看电影信息三个功能

因为消费者项目中需要:

  1. 导入提供者 jar 包(多个功能就有多个jar包,麻烦)
  2. 使用提供者暴露的接口

此处多个功能就有多个jar包,麻烦,所以规范化应该是如下结构:

  1. 定义一个公共接口项目:
    1. 定义实体类
    2. 定义接口
  2. 多个服务器ABC,实现提供者功能
    1. 引入公共接口项目的 jar 包
    2. 定义公共接口项目中的接口的实现类
    3. 定义spring配置文件,内容不需要变化,仍然是 4 步
    4. 添加监听器(创建spring容器对象),内容不需要变化
  3. 消费者项目:
    1. 现在只需要引入公共接口项目的 jar 包,就不需要引用多个 jar 包
    2. 定义spring配置文件,内容不需要变化,仍然是 2 步

2.5、dubbo 常用标签

Dubbo 中常用标签。分为三个类别:公用标签,服务提供者标签,服务消费者标签

2.5.1、公用标签

<dubbo:application/><dubbo:registry/>
  1. 配置应用信息

    <dubbo:application name="服务的名称/>
    
  2. 配置注册中心

    <dubbo:registry address="ip:port" protocol="协议"/>
    

2.5.2、提供者标签

配置访问服务提供者的协议信息

<dubbo:protocol name="dubbo" port="20880"/>

配置暴露的服务

<dubbo:service interface="服务接口名" ref="服务实现对象 bean"/>

2.5.3、消费者标签

配置服务消费者引用远程服务

<dubbo:reference id="服务引用 bean 的 id" interface="服务接口名"/>

2.5.4、关闭检查 check

服务启动时,会检查相关的依赖是否可用,如不可用则会抛出异常(比如此处必须先运行提供者的 Tomcat,否则报错)

关闭这个启动时检查:(比如先运行消费者,再运行的提供者,就需要关闭检查)

<dubbo:reference interface="com.service.UserService" check="false"/>

关闭注册中心启动时检查:

<dubbo:registry check="false"/>

2.5.5、请求重试 retries

远程服务调用重试次数,不包括第一次调用,默认是 2 次,加上第一次共 3 次

<dubbo:reference retries="5" />

3、注册中心-Zookeeper

现在在消费者项目的配置文件中,对于 引用远程服务接口 中的访问地址,是写死的,现在使用注册中心可以使其动态化,防止出现链接崩坏而导致的项目问题

服务注册中心可以通过特定协议来完成服务对外的统一

Dubbo 提供 的注册中心有如下几种类型可供选:

  • Multicast 注册中心:组播方式 (类似于广播,需要频道)
  • Redis 注册中心:使用 Redis 作为注册中心 (存入redis数据库)
  • Simple 注册中心:就是一个 dubbo 服务。作为注册中心。提供查找服务的功能。
  • Zookeeper 注册中心:使用 Zookeeper 作为注册中心

Zookeeper 是一个高性能的,分布式的,开放源码的分布式应用程序协调服务,简称 zk

Zookeeper 是翻译管理是动物管理员,可以理解为 windows 中的资源管理器或者注册表

他是一个树形结构,这种树形结构和标准文件系统相似,ZooKeeper 树中的每个节点被称为 Znode,和文件系统的目录树一样,ZooKeeper 树中的每个节点可以拥有子节点,每个节点表 示一个唯一服务资源

Zookeeper 运行需要 java 环境

3.1、安装配置 Zookeeper

3.1.1、Windows 平台 Zookeeper 安装,配置

下载的文件 zookeeper-3.5.4-beta.tar.gz 解压后到目录就可以了,例如 d:/servers/ zookeeper-3.5.4

修改 zookeeper-3.5.4/conf/ 目录下配置文件

复制一份 zoo-sample.cfg ,并改名为 zoo.cfg

文件内容:

  • tickTime:心跳的时间,单位毫秒

    Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳,表明存活状态

  • dataDir:数据目录,可以是任意目录

    存储 zookeeper 的快照文件、pid 文件,默认为 /tmp/zookeeper,建议在 zookeeper 安装目录下创建 data 目录,将 dataDir 配置改为 /usr/local/zookeeper-3.4.10/data

  • clientPort:客户端连接 zookeeper 的端口,即 zookeeper 对外的服务端口,默认为 2181

配置内容:

  1. dataDir :zookeeper 数据的存放目录

  2. admin.serverPort=8888

    原因:zookeeper 3.5.x 占用 8080

启动:

打开解压目录的 bin 目录,双击 zkServer.cmd ,启动服务器

zkCli.cmd 启动命令客户端

3.1.2、 Linux 平台 Zookeeper 安装、配置

Zookeeper 的运行需要 jdk。使用前 Linux 系统要安装好 jdk

①:上传 zookeeper-3.5.4-beta.tar.gz 并解压
解压文件执行命令:tar -zxvf zookeeper-3.5.4-beta.tar.gz -C /usr/local/

②:配置文件
在 zookeeper 的 conf 目录下,拷贝样例文件 zoo-sample.cfg 为 zoo.cfg,cp zoo_sample.cfg zoo.cfg
zookeeper 启动时会读取该文件作为默认配置文件

③:启动 Zookeeper
启动(切换到安装目录的 bin 目录下):./zkServer.sh start

④:关闭 Zookeeper
关闭(切换到安装目录的 bin 目录下):./zkServer.sh stop

3.2、使用 Zookeeper

  1. 将服务提供者注册到注册中心(暴露服务)

    1. 导入 dubbo 依赖、操作 ZooKeeper 的客户端 curator 依赖
    2. 配置服务提供者(spring配置文件)
      1. 声明服务的名称
      2. 声明ZooKeeper注册中心的地址
      3. 指定通信规则
      4. 暴露服务接口,ref指向真正的实现对象
  2. 让服务消费者去注册中心订阅服务提供者的服务地址

    1. 消费者需要引入和提供者一样的依赖

    2. 配置文件

      1. 声明服务的名称
      2. 声明ZooKeeper注册中心
      3. 引用远程服务接口

3.2.1、公共接口

仅提供实体类、需要暴露的公共接口

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>com.afei</groupId>
  <artifactId>dubbo-public-interface</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <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>

    <!-- lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.12</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

</project>
实体类、接口

注意实体类要实现序列化接口

@Data
public class User implements Serializable {
    private Integer id;
    private String username;
    private Integer age;
}
public interface UserService {
    User queryUser(Integer id);
}
结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UUL8l8GD-1649580916263)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220222233050711.png)]

3.2.2、服务提供者

需要引入公共接口项目打包为 jar 包,放入maven本地仓库作为依赖

怎么将项目打包为 jar ?并且打包同时放入maven本地仓库
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ggqFdqTf-1649580916264)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220221115109975.png)]

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>com.afei</groupId>
    <artifactId>user-provider</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <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>
        <!--curator-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>4.0.0</version>
        </dependency>
        <!--引入公共接口依赖-->
        <dependency>
            <groupId>com.afei</groupId>
            <artifactId>dubbo-public-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
接口实现类
public class UserServiceImpl implements UserService {
    @Override
    public User queryUser(Integer id) {
        User user = new User();
        user.setId(id);
        user.setUsername("lisi");
        user.setAge(id + 1);
        return user;
    }
}
配置文件
<?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 提供者的配置文件-->
    <!--声明服务的名称,自定义名字表示当前服务提供者
        name:自定义服务名称,一般使用项目名称,使用唯一值
              服务名称是 Dubbo 内部使用标识服务的
    -->
    <dubbo:application name="user-provider"/>
    <!--声明ZooKeeper注册中心的地址
           连接到本机,因为使用的是 Linux,使用IP地址,如果是Windows,使用localhost
           或者用<dubbo:registry protocol="zookeeper" address="192.168.162.128:2181"/>
    -->
    <dubbo:registry address="zookeeper://192.168.162.128:2181"/>
    <!-- 指定通信规则,访问服务协议的名称、端口 -->
    <dubbo:protocol name="dubbo" port="20880"/>
    <!--暴露服务接口
            interface:接口全限定名称
            ref:指定接口实现类的bean的id
    -->
    <dubbo:service interface="com.service.UserService" ref="userServiceImpl"/>
    <!--
		如果还有其他实现类,那么可以通过 version 来解决消费者想要调用哪个实现类的问题 
		<dubbo:service interface="com.service.UserService" ref="userServiceImpl"  
															version="2.0.0"/>
	-->
    <!--声明服务接口的实现类对象,真正提供接口的功能实现-->
    <bean id="userServiceImpl" class="com.serviceImpl.UserServiceImpl"/>
</beans>

对应着xml配置的 <dubbo:service><dubbo:reference>,注解是 @DubboService 和 @DubboReference

注:2.7.7 开始才增加这两个注解,之前使用的是@Service和@Reference

  1. @Service 只能定义在一个类上,表示一个服务的具体实现
  2. interfaceClass:指定服务提供方实现的 interface 的类
  3. interfaceName:指定服务提供方实现的 interface 的类名
  4. version:指定服务的版本号
  5. group:指定服务的分组
  6. export:是否暴露服务
  7. registry:是否向注册中心注册服务
  8. application:应用配置
  9. module:模块配置
  10. provider:服务提供方配置
  11. protocol:协议配置
  12. monitor:监控中心配置
  13. registry:注册中心配置

(从 8 到 13)需要提供的是对应的 spring bean 的名字

①、启动提供者一

注意:

关闭 Linux 防火墙、启动ZooKeeper服务、启动监控中心(运行 jar 包并访问 7001 端口)

第一种方式:在上面配置的基础上,仅需要创建一个类,来加载 spring 配置生成容器对象,并执行 start() 方法

加载 spring 配置
public class MainApplication {
    //必须保证此方法在运行,没有停止,注册中心中才可以有提供者存在
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext appc = new ClassPathXmlApplicationContext("provider.xml");
        appc.start();
        System.in.read();   //此句不可省
    }
}
结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lygHGUNy-1649580916265)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220222233331417.png)]

②、启动提供者二

注意:

关闭 Linux 防火墙、启动ZooKeeper服务、启动监控中心(运行 jar 包并访问 7001 端口)

第二种方式:在上面配置的基础上

  1. 配置 web.xml 方式,配置监听器,来生成 Spring 容器对象

  2. 配置 pom.xml 文件,添加 Tomcat 插件,启动 tomcat来启动 提供者服务

    注意更改端口号,将打包方式改成 war

web.xml文件

配置 spring 容器监听器

<!--声明监听器-->
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:provider.xml</param-value>
</context-param>
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
pom.xml 文件新增
<packaging>war</packaging>

<build>
    <plugins>
    <!-- 插件 Tomcat7 -->
    <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.1</version>
        <configuration>
            <port>8081</port> <!-- 端口 -->
            <path>/</path> <!-- 上下路径 -->
            <uriEncoding>UTF-8</uriEncoding> <!-- 针对 GET 方式乱码处理 -->
        </configuration>
    </plugin>
    </plugins>
</build>
结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BcqaZxfL-1649580916266)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220223105245826.png)]

3.2.3、服务消费者

需要引入公共接口项目打包为 jar 包,放入maven本地仓库作为依赖

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>com.afei</groupId>
    <artifactId>consumer</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <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>
        <!--curator-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>4.0.0</version>
        </dependency>
        <!--引入公共接口依赖-->
        <dependency>
            <groupId>com.afei</groupId>
            <artifactId>dubbo-public-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- 插件 Tomcat7 -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <port>8080</port> <!-- 端口 -->
                    <path>/</path> <!-- 上下路径 -->
                    <uriEncoding>UTF-8</uriEncoding> <!-- 针对 GET 方式乱码处理 -->
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
配置文件
<?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 http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- dubbo 消费者的配置文件-->
    <!--声明服务的名称(声明服务的操作是一样的)-->
    <!--声明服务的名称,自定义名字表示当前服务提供者
        name:自定义服务名称,一般使用项目名称,使用唯一值
              服务名称是 Dubbo 内部使用标识服务的
    -->
    <dubbo:application name="consumer"/>
    <!--声明ZooKeeper注册中心-->
    <dubbo:registry address="zookeeper://192.168.162.128:2181"/>
    <!--引用远程服务接口
            interface:dubbo服务接口全限定名称
            id:dubbo创建的代理对象的id,使用这个id访问代理对象
    -->
    <dubbo:reference interface="com.service.UserService" id="remoteUserService"/>
</beans>

对应着xml配置的 <dubbo:service><dubbo:reference>,注解是 @DubboService 和 @DubboReference

注:2.7.7开始才增加这两个注解,之前使用的是@Service和@Reference

  1. @Reference 可以定义在类中的一个字段上,也可以定义在一个方法上,甚至可以用来修饰另一个 annotation,表示一个服务的引用。通常 @Reference 定义在一个字段上
  2. interfaceClass:指定服务的 interface 的类
  3. interfaceName:指定服务的 interface 的类名
  4. version:指定服务的版本号
  5. group:指定服务的分组
  6. url:通过指定服务提供方的 URL 地址直接绕过注册中心发起调用
  7. application:应用配置
  8. module:模块配置
  9. consumer:服务消费方配置
  10. protocol:协议配置
  11. monitor:监控中心配置
  12. registry:注册中心配置

(从 7 到 12)需要提供的是对应的 spring bean 的名字

启动类就要使用 @EnableDubbo: 开启注解Dubbo功能 ,其中可以加入scanBasePackages属性配置包扫描的路径,用于扫描并注册bean

通过 @EnableDubbo 可以在指定的包名下(通过 scanBasePackages),或者指定的类中(通过 scanBasePackageClasses)扫描 Dubbo 的服务提供者(以 @Service 标注)以及 Dubbo 的服务消费者(以 Reference 标注)

SpringMVC 配置文件
<?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="com.service"/>

    <mvc:annotation-driven/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
web.xml
<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <!--声明中央调度器-->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springmvc.xml,classpath:consumer.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
service、controller
@Component
public class ConsumerService {
    @Resource
    private UserService userService;
    public void printTest(Integer userid){
        User user = userService.queryUser(userid);
        System.out.println(user);
    }
}
@Controller
public class MyController {
    @Resource
    private ConsumerService service;

    @RequestMapping("/test")
    public String tt(Integer id){
        service.printTest(id);
        return "hello";
    }
}
结构

4、监控中心

4.1、什么是监控中心

dubbo 的使用,其实只需要有注册中心,消费者,提供者这三个就可以使用了,但是并不能看到有哪些消费者和提供者,为了更好的调试,发现问题,解决问题,因此引入 dubbo-admin

通过 dubbo-admin 可以对消费者和提供者进行管理。可以在 dubbo 应用部署做动态的调整, 服务的管理

  • dubbo-admin:图形化的服务管理页面;安装时需要指定注册中心地址,即可从注册中心中获取到所有的提供者 / 消费者进行配置管理
  • dubbo-monitor-simple:简单的监控中心

4.2、发布配置中心

1、下载监控中心,https://github.com/alibaba/dubbo

到官网的 GitHub页面,拉到最下面,点击 dubbo admin

这里下载的是源代码,需要手工编译才能使用
下载

2、 进入目录,修改dubbo-admin配置

修改 src\main\resources\application.properties 指定zookeeper地址
如果启动的 ZooKeeper 是 Windows 版本的,地址就如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2p4tsUgf-1649580916267)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220222170847308.png)]

如果启动的 ZooKeeper 是 Linux 版本的,地址就填虚拟机地址:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rsQDj87o-1649580916268)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220222173544588.png)]

3、 打包dubbo-admin

进入 pom.xml 文件所在的目录。在目录栏使用 cmd ,打开命令窗口
执行命令: mvn clean package 清理并打包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3vjixcDV-1649580916268)(C:\Users\ASUS\AppData\Roaming\Typora\typora-user-images\image-20220223163004417.png)]

打包好后,会在 target 目录下出现 jar 包

4、运行dubbo-admin

将jar包挪出来,然后在 jar 包所在目录位置 cmd

注意:

  • jdk版本时 1.8
  • 要保证 ZooKeeper 在 jdk1.8版本下运行

执行命令:java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
启动后不关闭窗口,在浏览器访问端口 7001

默认使用root/root 登陆

5、负载均衡

负载均衡是以集群为前提,将工作任务进行平衡、分摊到多个操作单元上进行执行

负载均衡有两个方面的含义:

  1. 单个重负载的工作分配到多台服务器做并行处理,每个服务器处理之后将结果汇总,返回给用户,系统处理能力增强
  2. 大量的并发访问或数据流量分摊到多台服务器处理,减少用户等待响应时间

5.1、负载策略

RandomLoadBalance(默认)

随机,按权重设置随机概率

RoundRobinLoadBalance

轮循,按公约后的权重设置轮循比率

存在慢的提供者累计请求问题,服务器性能相近时使用

LeastActiveLoadBalance

最少活跃调用书,系统活跃数的随机,活跃数指调用前后计数差

服务器性能相差较大时使用

ConsistentHashLoadBalance

一致性 Hash,相同参数的请求总是发到同一提供者,当某一提供者挂是,将需求会平摊到其他提供者

对故障的处理波动较小

5.2、代码实现

需要是集群环境中实现

配置方式:

<dubbo:reference interface="..." loadbalance="roundrobin"/><dubbo:service interface="..." loadbalance="roundrobin"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值