文章目录:

1.RPC & 软件架构

1.1 单一应用架构

1.2 分布式微服务架构

1.3 RPC

2.Dubbo概述

2.1基本架构

2.2 dubbo支持的协议

3.直连方式实现dubbo

3.1 服务提供者的创建

3.2 服务消费者的创建

3.3 启动测试!!!


1.RPC & 软件架构

1.1 单一应用架构

当网站流量很小时,应用规模小时,只需一个应用,将所有功能都部署在一起,以减少部署服务器数量和成本。此时,用于简化增删改查工作量的数据访问框架(ORM) 是关键。数据库的处理时间影响应用的性能。

Dubbo——初识RPC、Dubbo框架、使用直连方式实现Dubbo_xml

这种结构的应用适合小型系统,小型网站,或者企业的内部系统,用户较少,请求量不大,对请求的处理时间没有太高的要求。 将所有功能都部署到一个服务器,简单易用。开发项目的难度低。


缺点:

        1、性能扩展比较困难

        2、不利于多人同时开发

        3、不利于升级维护

        4、整个系统的空间占用比较大

1.2 分布式微服务架构


分布式系统是若干独立计算机(服务器)的集合,这些计算机对于用户来说就像单个相关系统,分布式系统(distributed system )是建立在网络之上的服务器端一种结构。分布式系统中的计算机可以使用不同的操作系统,可以运行不同应用程序提供服务,将服务分散部署到多个计算机服务器上。



当应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的 分布式服务框架 (RPC) 是关键。分布式系统将服务作为独立的应用,实现服务共享和重用。

Dubbo——初识RPC、Dubbo框架、使用直连方式实现Dubbo_xml_02

 

1.3 RPC

RPC 【 Remote Procedure Call 】是指远程过程调用,是一种进程间通信方式,是一种技术思想,而不是规范。它允许程序调用另一个地址空间(网络的另一台机器上)的过程或函数,而不用开发人员显式编码这个调用的细节。调用本地方法和调用远程方法一样。

Dubbo——初识RPC、Dubbo框架、使用直连方式实现Dubbo_spring_03

 

RPC 调用过程:通讯是基于 TCP或 UDP协议;序列化方式(xml/json/二进制)

  1. 调用方 client 要使用右侧 server 的功能(方法),发起对方法的调用
  2. client stub 是 RPC 中定义的存根,看做是 client 的助手。stub 把要调用的方法参数进行序列化,方法名称和其他数据包装起来。
  3. 通过网络 socket(网络通信的技术),把方法调用的细节内容发送给右侧的 server
  4. server 端通过 socket 接收请求的方法名称、参数等数据,传给 stub。
  5. server 端接到的数据由 serverstub(server 的助手)处理,调用 server 的真正方法,处理业务
  6. server 方法处理完业务,把处理的结果对象(Object)交给了助手,助手把 Object 进行序列化,对象转为二进制数据。
  7. server 助手二进制数据交给网络处理程序
  8. 通过网络将二进制数据,发送给 client。
  9. client 接数据,交给 client 助手。
  10. client 助手,接收数据通过反序列化为 java 对象(Object),作为远程方法调用结果。

2.Dubbo概述

Apache Dubbo (incubating) |ˈdʌbəʊ| 是一款高性能、轻量级的开源 Java RPC 框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案、 服务治理方案。

官网:Apache Dubbo

2.1基本架构

Dubbo——初识RPC、Dubbo框架、使用直连方式实现Dubbo_spring_04

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

2.2 dubbo支持的协议

支持多种协议:dubbo , hessian , rmi , http, webservice , thrift , memcached , redis。

dubbo 官方推荐使用 dubbo 协议。dubbo 协议默认端口 20880

使用 dubbo 协议,spring 配置文件加入:<dubbo:protocol name="dubbo" port="20880" />


3.直连方式实现dubbo

点对点的直连项目:消费者直接访问服务提供者,没有注册中心。消费者必须指定服务提供者的访问地址(url)。

消费者直接通过 url 地址访问固定的服务提供者。这个 url 地址是不变的。

Dubbo——初识RPC、Dubbo框架、使用直连方式实现Dubbo_java_05

3.1 服务提供者的创建

1.创建一个maven web工程:服务的提供者,添加需要的依赖
2.创建一个实体bean查询的结果(必须实现序列化)
3.提供一个服务接口:xxxx
4.实现这个服务接口:xxxxImpl
5.配置dubbo服务提供者的核心配置文件
   a.声明dubbo服务提供者的名称:保证唯一
   b.声明dubbo使用的协议和端口号
   c.暴露服务,使用直连方式
6.添加监听器,读取配置文件信息

代码如下:👇👇👇(代码顺序对应上面的序号)

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>dubbo</artifactId>
      <version>2.6.2</version>
    </dependency>
package com.szh.dubbo.model;

import java.io.Serializable;

/**
 *
 */
public class User implements Serializable {

    private Integer id;
    private String name;
    private Integer age;

    //getter and setter
}
package com.szh.dubbo.service;

import com.szh.dubbo.model.User;

/**
 *
 */
public interface UserService {

    User queryUserById(Integer id);
}
package com.szh.dubbo.service.impl;

import com.szh.dubbo.model.User;
import com.szh.dubbo.service.UserService;

/**
 *
 */
public class UserServiceImpl implements UserService {
    @Override
    public User queryUserById(Integer id) {

        User user=new User();
        user.setId(id);
        user.setName("张起灵");
        user.setAge(21);

        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服务提供者的名称:保证唯一性 -->
    <dubbo:application name="001-link-userservice-provider"/>

    <!-- 设置dubbo使用的协议和端口号 -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- 暴露服务接口 -->
    <dubbo:service interface="com.szh.dubbo.service.UserService" ref="a" registry="N/A"/>

    <!-- 将业务接口的实现类加载到Spring容器中 -->
    <bean id="a" class="com.szh.dubbo.service.impl.UserServiceImpl"/>

</beans>
<?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">

    <!-- 读取dubbo配置文件信息 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dubbo-userservice-provider.xml</param-value>
    </context-param>
    <!-- 配置Spring的监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

3.2 服务消费者的创建

1.创建一个maven web工程:服务的消费者2.配置pom文件:添加需要的依赖(spring,dubbo)3.编写controller 4.设置dubbo的核心配置文件() 5.配置中央调度器(就是一个servlet:DispatcherServlet)

代码如下:(代码顺序对应上面的序号)

服务提供者接口中的方法要给消费者使用,消费者项目需要知道接口名称和接口中的方法名称、参数等。这些信息服务提供者才知道。需要把服务提供者接口对应工程的 class 文件打包为 jar 。

服务接口项目的类文件打包为 jar, 安装到 maven 仓库,仓库中的提供者 jar 可以被消费者使用。

使用 idea 的 maven 生命周期中的 install 命令进行打包(打包的时候将pom文件中的 <packaging>war</packaging> 内容注释掉,因为在服务消费者的pom文件中进行依赖项的导入是一个jar包)。也就是下面pom文件中的最后一个依赖项。

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>dubbo</artifactId>
      <version>2.6.2</version>
    </dependency>

    <dependency>
      <groupId>com.szh.dubbo</groupId>
      <artifactId>001-link-userservice-provider</artifactId>
      <version>1.0.0</version>
    </dependency>
package com.szh.dubbo.controller;

import com.szh.dubbo.model.User;
import com.szh.dubbo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 *
 */
@Controller
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping(value = "/user")
    public String userDetail(Integer id, Model model) {
        User user=userService.queryUserById(id);
        model.addAttribute("user",user);
        return "userDetail";
    }
}
<?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"/>

    <!-- 引用远程接口服务 -->
    <dubbo:reference interface="com.szh.dubbo.service.UserService"
                     id="userService"
                     url="dubbo://localhost:20880"
                     registry="N/A"/>

</beans>
<?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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 组件扫描器,扫描controller包下的注解 -->
    <context:component-scan base-package="com.szh.dubbo.controller"/>

    <!-- 开启SpringMVC注解驱动 -->
    <mvc:annotation-driven/>

    <!-- 配置视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>
<?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">

    <!-- 配置SpringMVC的中央调度器,读取Spring、Dubbo配置文件信息 -->
    <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>
<%@ page contentType="text/html;charset=utf-8" language="java" %>
<html>
<head>
    <title>$</title>
</head>
<body>
    <h1>用户详情</h1>
    <div>用户编号:${user.id}</div>
    <div>用户姓名:${user.name}</div>
</body>
</html>

3.3 启动测试!!!

上面两步,我们已经创建好了服务提供者和服务消费者,下面分别为这两个maven web工程配置各自的tomcat服务器。

配置信息如下:👇👇👇(均不设置上下文根)

Dubbo——初识RPC、Dubbo框架、使用直连方式实现Dubbo_java_06

Dubbo——初识RPC、Dubbo框架、使用直连方式实现Dubbo_spring_07

配置好Tomcat之后,我们就可以启动测试了,这里需要注意的是:一定要先启动第一个maven web工程(服务提供者)的tomcat服务器;启动成功后,再启动第二个maven web工程的(服务消费者)tomcat服务器。因为顾名思义:肯定是先有提供,才能进行消费啊。

下面是测试结果:👇👇👇(访问控制层中的请求路径,可以正确的拿到数据,这就说明我们使用直连方式实现了dubbo)

Dubbo——初识RPC、Dubbo框架、使用直连方式实现Dubbo_java_08