Java经典框架之Dubbo

news2024/11/25 0:39:00

Dubbo

Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机,Java 仍是企业和开发人员的首选开发平台。
  

课程内容的介绍

1. Dubbo概述
2. Dubbo基本应用
3. Dubbo实战案例
     

一、Dubbo概述

1、Dubbo及架构变化
1.1 Dubbo 介绍
Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的RPC 实现服务的输出和输入功能,可以和 Spring 框架无缝集成。Dubbo 框架,是基于容器运行的.。容器是 Spring。
官方网站 : http://dubbo.apache.org/
阿里巴巴已经将 dubbo 框架捐献给了 Apache 软件基金会。

  
现在出去找工作如果不会点分布式和微服务相关的内容,都不太好更面试官扯蛋。但这些架构也不是突然就出现的,而是经过不但演变才出现及流行起来的,本文就给大家来梳理下java项目架构的演变历程。
  
系统架构演化历程
单体架构
  大型网站都是从小型网站发展而来的,网站架构也是一样,是从小型网站架构逐步演化而来的,小型网站最开始没有太多人访问,只需要一台服务器就绰绰有余了,这时的架构如下:

  

应用程序、数据库、文件等所有的资源都在一台服务器上,通常服务器操作系统使用Linux、应用程序使用java或者其他语句,然后部署在Apache或者Nginx上。数据库使用MySQL,使用开源的技术实现,然后部署在一台廉价的服务器上就开始了网站的发展之路。

      

应用服务和数据服务分离
  好景不长,随着公司业务的发展,一台服务逐渐满足不了需求,越来越多的用户访问导致性能越来越差,数据存储空间开始不足,这时我们需要将应用和数据分离,分离后开始使用三台服务器:应用服务器、文件服务器、数据库服务器。如图:

  

应用和数据分离后,不同特性的服务器承担着不同的服务角色,网站的并发处理能力和数据存储空间都得到了很大的改善,支持网站业务进一步发展,但是随着用户逐渐增多,数据库压力越来越大,访问延迟,进而影响整个网站的性能,此时需要进一步优化。

缓存的使用
  网站访问有个著名的二八定律,即80%的业务集中访问在20%的数据上,如果我们将这一小部分的数据缓存在内存中,能够很好的减少数据库的访问压力,提高整个网站的数据访问速度。

   

缓存常用的组件可以是Redis,ehcache等。

    
集群的使用
  缓存解决了数据库访问量比较大的问题,但是并不能解决随着业务增多造成的服务器并发压力大的问题,这时我们需要增加一台应用服务器来分担原来服务器的访问压力和存储压力。如图:

  

通过负载均衡调度服务器,可将来自用户的访问请求分发到应用服务器中的任何一台服务器中,这样多台服务器就分担了原来一台服务器的压力,我们只需要注意会话的一致性就可以了。

  

数据库读写分离
  系统正常运行了一段时间后,虽然加的有缓存,使绝大多数的数据库操作可以不通过数据库就能完成,但是任然有一部分的操作(缓存访问不命中,缓存过期)和全部的写操作需要访问数据库,当用户达到一定规模后,数据库因为负载压力过大还是会成为系统的瓶颈,
  这时主流的数据库都提供的有主从热备份功能,通过配置两台数据库实现主从关系,可以将一台数据库服务器的数据更新同步到另一台服务器上。可以利用这一功能来实现数据库读写分离。从而改善数据库的负载压力,如图:

  

mysql的读写分离可以通过自身自带的从主复制实现,Oracle的话可以通过阿里巴巴的mycat组件来实现。

  

反向代理和CDN加速
  为了应付复杂的网络环境和不同地区用户的访问,通过CDN和反向代理加快用户访问的速度,同时减轻后端服务器的负载压力。CDN与反向代理的基本原理都是缓存。CDN部署在网络提供商的机房。用户请求到来的时候从距离自己最近的网络提供商机房获取数据,而反向代理则部署在网站的中心机房中,请求带来的时候先去反向代理服务器中查看请求资源,如果有则直接返回。如图:

  

使用CDN和反向代理的目的都是尽早返回数据给用户,一方面加快用户的访问速度,另一方面也减轻后端服务器的负载压力。

  

分布式文件和分布式数据库
  任何强大的单一服务器都满足不了大型网站持续增长的业务需求。数据库经过读写分离后,从一台服务器拆分成两天服务器,但是随着业务的增长后面依然不能满足需求,这时我们需要使用分布式数据库,同时文件系统也一样,需要使用分布式文件系统。
  分布式数据库是数据库拆分的最后的手段,只有在表单数据规模非常庞大的时候才使用,不到不得已时,我们更常用的手段是业务分库,将不同的业务数据部署在不同的物理服务器上。

  

NoSql和搜索引擎
  随着业务越来越复杂,对数据存储和检索的需求也越来越复杂,这时一些NoSQL(Reids,HBase,mongodb)数据库技术和搜索引擎(Solr,Elasticsearch)的时候就显得很有必要。如下图:

     

NoSQL和搜索引擎对可伸缩的分布式特性具有更好的支持,应用服务器通过一个统一的数据访问模块访问各种数据,减轻应用程序管理诸多数据源的麻烦。

  

业务拆分
  当访问量达到一定规模的时候我们可以通过分而治之的手段将整个系统的业务分成不同的产品线,例如我们将系统的首页,商铺,订单,买家,卖家,支付,订单等拆分成不同的产品线。
  具体到技术实现上,也可以根据产品线划分,将一个网站拆分成许多不同的应用,每个应用独立部署维护,应用之间通过RPC框架(dubbo,webService,httpClient…)建立连接,也可以通过消息队列实现异步分发处理。来构成一个完整的系统,如下图:

  

分布式服务
随着业务拆分越来越小,存储系统越来越庞大,应用系统的整体复杂度呈指数级增加,部署维护越来越困难,由于所有应用要和所有数据库系统连接,最终导致数据库连接资源不足,拒绝服务。

1.当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。
2.当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述应用的架构关系。
3.接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?
4.服务多了,沟通成本也开始上升,调某个服务失败该找谁?服务的参数都有什么约定?
5.一个服务有多个业务消费者,如何确保服务质量?
6.随着服务的不停升级,总有些意想不到的事发生,比如cache写错了导致内存溢出,故障不可避免,每次核心服务一挂,影响一大片,人心慌慌,如何控制故障的影响面?服务是否可以功能降级?或者资源劣化?

   
解决方案:公共的应用模块被提取出来,部署在分布式服务器上供应用服务器调用。也就是我们将的分布式服务或者微服务。

  
1.2 单体架构
单体架构也称之为单体系统或者是单体应用。就是一种把系统中所有的功能、模块耦合在一个应用中的架构方式。其优点为:项目易于管理、部署简单。缺点:测试成本高、可伸缩性差、可靠性差、迭代困难、跨语言程度差、团队协作难。
  
1.3 SOA 架构:
面向服务的架构(SOA- Service-Oriented Architecture)是一个组件模型,它将应用程序拆分成不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。
  
1.4 RPC 远程过程调用
远程过程调用协议( Remote Procedure Call Protocol),它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC 协议假定某些传输协议的存在,如 TCP 或 UDP,为通信程序之间携带信息数据。在 OSI 网络通信模型中,RPC 跨越了传输层和应用层。RPC 使得开发包括网络分布式多程序在内的应用程序更加容易。
  
2、Dubbo 框架结构图
2.1 Dubbo 角色介绍

  
registry
注册中心是用于发布和订阅服务的一个平台.用于替代 SOA 结构体系框架中的 ESB 服务总线的。
  
发布
开发服务端代码完毕后,将服务信息发布出去. 实现一个服务的公开。

 

订阅
客户端程序,从注册中心下载服务内容 这个过程是订阅。
订阅服务的时候,会将发布的服务所有信息,一次性下载到客户端.客户端也可以自定义,修改部分服务配置信息。如: 超时的时长, 调用的重试次数等。
   
consumer
服务的消费者, 就是服务的客户端。
消费者必须使用 Dubbo 技术开发部分代码. 基本上都是配置文件定义。
  
provider
服务的提供者, 就是服务端。
服务端必须使用 Dubbo 技术开发部分代码. 以配置文件为主。
  
container
容器. Dubbo 技术的服务端(Provider), 在启动执行的时候, 必须依赖容器才能正常启动。
默认依赖的就是 Spring 容器. 且 Dubbo 技术不能脱离 Spring 框架。
在 2.5.3 版本的 dubbo 中, 默认依赖的是 spring2.5 版本技术. 可以选用 Spring4.5 以下版本。
在 2.5.7 版本的 dubbo 中, 默认依赖的是 spring4.3.10 版本技术. 可以选择任意的 spring版本。
  
monitor
监控中心,是 Dubbo 提供的一个jar工程。
主要功能是监控服务端(Provider)和消费端(Consumer)的使用数据的。 如:服务端是什么,有多少接口,多少方法,调用次数,压力信息等。客户端有多少,调用过哪些服务端,调用了多少次等。

   
2.2 Dubbo 执行流程
start:启动 Spring 容器时,自动启动 Dubbo 的 Provider。
register:Dubbo 的 Provider 在启动后自动会去注册中心注册内容注册的内容包括:
1.1 Provider 的 IP。
1.2 Provider 的端口。
1.3 Provider 对外提供的接口列表,哪些方法,哪些接口类。
1.4 Dubbo 的版本。
1.5 访问 Provider 的协议。
subscribe: 订阅.当 Consumer 启动时,自动去 Registry 获取到所已注册的服务的信息。
notify: 通知.当 Provider 的信息发生变化时,自动由 Registry 向 Consumer 推送通知。
invoke: 调用. Consumer 调用 Provider 中方法。
1.1 同步请求.消耗一定性能.但是必须是同步请求,因为需要接收调用方法后的结果。
count:次数. 每隔 2 分钟,provoider 和 consumer 自动向 Monitor 发送访问次数.Monitor进行统计。
  

3.Dubbo 支持的协议
3.1Dubbo 协议(官方推荐协议)

  
3.2RMI(Remote Method Invocation)协议

  
3.3Hessian 协议

  
4.Dubbo 支持的注册中心
4.1Zookeeper(官方推荐)
1. 优点:
支持分布式.很多周边产品。
2. 缺点:
受限于 Zookeeper 软件的稳定性。Zookeeper 专门分布式辅助软件,稳定较优。
  
4.2 Multicast
1. 优点:
去中心化,不需要单独安装软件。
2. 缺点:
Provider 和 Consumer 和 Registry 不能跨机房(路由)。
  
4.3Redis
1. 优点:
支持集群,性能高。
  
2. 缺点:
要求服务器时间同步。否则可能出现集群失败问题。
   
4.4Simple
1. 优点:
标准 RPC 服务。没有兼容问题。
2. 缺点:
不支持集群。
  

二、Dubbo基本应用

1. Dubbo基本案例
实现项目之间的调用。
  
1.1 项目结构

  
1.2 公共模块
在commons模块中定义个service接口即可。
package com.bobo;

public interface UserService {

    String sayHello(String name);

}
  

  
1.3 provider
创建服务提供者。
    <dependencies>
        <!-- 添加commons模块 -->
        <dependency>
            <groupId>com.bobo</groupId>
            <artifactId>dubbo-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--- 添加Spring依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- dubbo的依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.5.3</version>
            <exclusions>
                <exclusion>
                    <groupId>spring</groupId>
                    <artifactId>org.springframework</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- Zookeeper的客户端 -->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
    </dependencies>
  
创建服务端提供的服务。
package com.bobo.service;

import com.bobo.service.UserService;

public class UserServiceImpl implements UserService {
    @Override
    public String sayHello(String name) {

        System.out.println("服务端执行了: " + name);
        return "HELLO:" + name + "[msg]";
    }
}
  
添加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: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://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">


    <!-- 提供方应用信息 -->
    <dubbo:application name="dubboProvider" />
    <!-- 配置Zookeeper注册中心 -->
    <dubbo:registry protocol="zookeeper"
                    address="192.168.100.120:2181,192.168.100.121:2181,192.168.100.122:2181"/>
    <!-- 开启监控 -->
    <dubbo:monitor protocol="registry" />
    <!-- 设置Dubbo使用的协议 -->
    <dubbo:protocol name="dubbo" port="20880" />


    <!-- 注入UserServiceImpl -->
    <bean class="com.bobo.service.UserServiceImpl" id="userService"/>

    <!-- 声明需要对外暴露的服务 -->
    <dubbo:service interface="com.bobo.service.UserService" ref="userService"
        group="dubbo" version="1.0.0" timeout="5000"
    />

</beans>
  
为了看到日志效果,我们添加log4j.properties文件。
log4j.rootLogger=INFO,A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
   
添加启动文件。
package com.bobo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppStart {

    public static void main(String[] args) throws Exception{
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 挂起当前线程
        Thread.currentThread().join();
    }
}
  
启动后效果。

  
我们在Zookeeper中可以看到提供者的相关的注册信息。

  
1.4 consumer
服务消费者
引入相关的依赖(和provide中的依赖是一样的)
    <dependencies>
        <!-- 添加commons模块 -->
        <dependency>
            <groupId>com.bobo</groupId>
            <artifactId>dubbo-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--- 添加Spring依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- dubbo的依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.5.3</version>
            <exclusions>
                <exclusion>
                    <groupId>spring</groupId>
                    <artifactId>org.springframework</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- Zookeeper的客户端 -->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
    </dependencies>
  
创建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: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://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">


    <!-- 消费者应用信息 -->
    <dubbo:application name="dubboConsumer" />

    <!-- 配置和Provide相同的注册中心 -->
    <dubbo:registry protocol="zookeeper"
                address="192.168.100.120:2181,192.168.100.121:2181,192.168.100.122:2181" />

    <!-- 开启监控 -->
    <dubbo:monitor protocol="registry" />

    <!-- 生成远程连接的服务代理 -->
    <dubbo:reference interface="com.bobo.service.UserService" id="userService"
        group="dubbo" version="1.0.0" timeout="5000"
    />



</beans>
  
添加对应的日志文件。
创建测试的代码
package com.bobo;


import com.bobo.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppStart {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取接口的代理对象
        UserService userService = (UserService) ac.getBean("userService");
        System.out.println(userService.sayHello("aaa"));

    }
}
  
1.5 测试
先启动服务端代码。

  
启动消费者程序。

  
获取结果的输出。

  
消费者消费后我们在Zookeeper的注册中心中是可以看到新的注册信息的。

  
2. Dubbo源码下载和编译
https://github.com/apache/incubator-dubbo/tree/2.5.x?utm_source=csdn_toolbar

  
解压缩

  
进入dubbo-2.5.10目录下执行 mvn clean package -Dmaven.test.skip=true 会生成如下结果[注意:以管理员身份进入]
  
看到如下提示表示编译成功。

  
核对我们需要的内容。

  

    
3. 管理控制台
开源的dubbo服务管理控制台是阿里巴巴内部裁剪的版本,开源的部分功能包括:路由规则,动态配置,服务降级,访问控制,权重调整,负载均衡等管理功能。将生成的dubbo-admin-2.5.10.war拷贝到web容器中(此处使用tomcat8)

  
解压缩后我们需要修改dubbo的属性文件。

  
dubbo.registry.address=zookeeper://192.168.100.120:2181?
backup=192.168.100.121:2181,192.168.100.122:2181
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest
   
启动Tomcat服务即可。
登录的地址:http://localhost:8080/dubbo-admin-2.5.10/
默认的账号密码是 root root
  

  
将页面语音切换到中文。

  
4. 监控平台
Dubbo-Monitor主要是用来统计服务和调用次数和调用时间,服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心,监控中心则使用数据绘制图表来显示。
  
4.1 开启monitor服务
我们需要在消费者和服务提供者中都开启monitor服务,我们只需要在对应的配置文件中添加如下信息即可。
<!-- 开启监控 -->
<dubbo:monitor protocol="registry" />
  

  
4.2 修改配置

  
解压缩后的结构。

  
修改配置进入conf目录中 添加Zookeeper注册中心的信息。
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
dubbo.container=log4j,spring,registry,jetty
dubbo.application.name=simple-monitor
dubbo.application.owner=
# zookeeper的配置信息
dubbo.registry.address=zookeeper://192.168.100.120:2181?
backup=192.168.100.121:2181,192.168.100.122:2181
#dubbo.registry.address=zookeeper://127.0.0.1:2181
#dubbo.registry.address=redis://127.0.0.1:6379
#dubbo.registry.address=dubbo://127.0.0.1:9090
dubbo.protocol.port=7070
dubbo.jetty.port=8080
dubbo.jetty.directory=${user.home}/monitor
dubbo.charts.directory=${dubbo.jetty.directory}/charts
dubbo.statistics.directory=${user.home}/monitor/statistics
dubbo.log4j.file=logs/dubbo-monitor-simple.log
dubbo.log4j.level=WARN
  
4.3 启动监控服务
启动服务的程序在bin目录下。

  

  
4.4 访问服务
http://localhost:8084
访问成功的页面

  

三、Dubbo实战案例

1、案例介绍
1.1 案例结构图

  
1.2 需求
完成对用户表的CRUD操作。
  
1.3 技术选型
MySQL、Dubbo、Zookeeper、Maven、MyBatis、SpringMVC、Spring。
  
1.4 表结构
CREATE TABLE `users` (
    `userid` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(30) DEFAULT NULL,
    `userage` int(11) DEFAULT NULL,
    PRIMARY KEY (`userid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
   
2、项目创建
2.1 项目设计
整个案例工程会通过Maven聚合工程来创建,先来设计Maven聚合工程的项目结构。
dubbo-parent(POM)
    |-- dubbo-pojo(jar)
    |-- dubbo-mapper(jar)
    |-- dubbo-user-provider(POM)
        |-- dubbo-user-provider-interface(jar)
        |-- dubbo-user-provider-service(jar)
    |-- dubbo-user-consumer(POM)
        |-- dubbo-user-consumer-web-service(jar)
        |-- dubbo-user-consumer-web(war)
  
2.2 创建dubbo-parent

  
在对应的pom文件中声明如下信息。
    <!-- jar包的依赖注入 ,由于该工程是一个父工程,所以jar包在该pom文件中只是声明 -->
    <dependencyManagement>
        <dependencies>
            <!-- 单元测试 -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
            <!-- 日志处理 -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <!-- Mybatis -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>${mybatis.spring.version}</version>
            </dependency>
            <!-- MySql -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!-- 连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <!-- Spring -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <!-- JSP相关 -->
            <dependency>
                <groupId>jstl</groupId>
                <artifactId>jstl</artifactId>
                <version>${jstl.version}</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>${servlet-api.version}</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jsp-api</artifactId>
                <version>${jsp-api.version}</version>
                <scope>provided</scope>
            </dependency>
            <!-- dubbo -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>dubbo</artifactId>
                <version>${dubbo-version}</version>
            </dependency>
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>${zkClient-version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
        </resources>
        <!-- tomcat插件,由于子项目不一定每个都是web项目,所以该插件只是声明,并未开启 -->
        <pluginManagement>
            <plugins>
                <!-- 配置Tomcat插件 -->
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>${tomcat.version}</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
  
2.2 创建dubbo-pojo
项目结构

  
User实体对象
package com.bobo.pojo;

import java.io.Serializable;

public class User implements Serializable {

    private Integer userid;

    private String username;

    private Integer userage;

    public Integer getUserid() {
        return userid;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getUserage() {
        return userage;
    }

    public void setUserage(Integer userage) {
        this.userage = userage;
    }

    public User() {
    }

    public User(Integer userid, String username, Integer userage) {
        this.userid = userid;
        this.username = username;
        this.userage = userage;
    }

    @Override
    public String toString() {
        return "User{" +
                "userid=" + userid +
                ", username='" + username + '\'' +
                ", userage=" + userage +
                '}';
    }
}
  
2.3 创建dubbo-mapper
持久层项目

  
创建UserMapper接口。
/**
* UserMapper接口
*/
public interface UserMapper {
}
   
创建UserMapper的映射文件。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD
Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.bobo.mapper.UserMapper">

</mapper>
  
修改POM文件,添加相关的依赖。
    <dependencies>
        <dependency>
            <groupId>com.bobo</groupId>
            <artifactId>dubbo-pojo</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!-- Mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
        </dependency>
        <!-- MySql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- 连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
   
2.4 创建服务提供者
2.4.1 创建dubbo-user-provider
直接创建出来即可。

  
2.4.2 创建dubbo-user-provider-interface

   
添加dubbo-pojo的依赖。
    <dependencies>
        <dependency>
            <groupId>com.bobo</groupId>
            <artifactId>dubbo-pojo</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    <dependencies>
  
2.4.3 创建dubbo-user-provider-service

  
修改POM文件,添加相关的依赖。
    <dependencies>
        <dependency>
            <groupId>com.bobo</groupId>
            <artifactId>dubbo-user-provider-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>com.bobo</groupId>
            <artifactId>dubbo-mapper</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

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

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>

        <!-- dubbo的依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.5.3</version>
            <exclusions>
                <exclusion>
                    <groupId>spring</groupId>
                    <artifactId>org.springframework</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- Zookeeper的客户端 -->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
    </dependencies>
  
创建db.properties文件。
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/shop?characterEncoding=utf-8&serverTimezone=UTC
jdbc.username=root
jdbc.password=123456
  
SqlMapperClient.xml MyBatis的配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

</configuration>
  
applicationContext-service.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:p="http://www.springframework.org/schema/p"
       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/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 扫描bean对象 -->
    <context:component-scan base-package="com.bobo.dubbo.service.impl"/>
</beans>
  
applicationContext-trans.xml事务配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

    <!-- 配置事物管理器的切面 -->
    <bean id="transactionMananger" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 配置事物传播行为 :其实就是那些方法应该受什么样的事物控制-->
    <tx:advice id="advice" transaction-manager="transactionMananger">
        <tx:attributes>
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="modify*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="dorp*" propagation="REQUIRED"/>
            <tx:method name="del*" propagation="REQUIRED"/>
            <tx:method name="find*" read-only="true"/>
        </tx:attributes>
    </tx:advice>

    <!-- 那些类下的方法需要参与到当前的事物管理中 。配置切点 -->
    <aop:config>
        <aop:advisor advice-ref="advice" pointcut="execution(* com.bobo.dubbo.service.impl*.*(..))"/>
    </aop:config>
</beans>
     
applicationContext-dao.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:p="http://www.springframework.org/schema/p"
       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/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 配置解析properties文件的工具类 -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!-- 配置数据源 dataSource -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="maxActive" value="10" />
        <property name="minIdle" value="5" />
    </bean>

    <!-- 创建mybatis的上下文对象  -->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource">
            <ref bean="dataSource"/>
        </property>
        <property name="configLocation">
            <value>classpath:SqlMapperClient.xml</value>
        </property>
    </bean>

    <!-- 扫描mybatis的接口与映射配置文件 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.bobo.mapper"/>
    </bean>
</beans>
   
然后在classpath:/META-INF/spring目录下创建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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       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://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://code.alibabatech.com/schema/dubbo
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 导入Spring相关的配置文件 -->
    <import resource="../../applicationContext-dao.xml" />
    <import resource="../../applicationContext-service.xml" />
    <import resource="../../applicationContext-trans.xml" />

    <dubbo:application name="user-provider" />
    <dubbo:registry protocol="zookeeper"
                    address="192.168.100.120:2181,192.168.100.121:2181,192.168.100.122:2181"/>

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

    <!-- 添加向Zookeeper注册的服务 -->
    <dubbo:service interface="com.bobo.dubbo.service.AddUserDubboService"
                   ref="addUserDubboServiceImpl" group="dubbo" version="1.0.0" timeout="5000"/>

    <dubbo:service interface="com.bobo.dubbo.service.SelectUserDubboService"
                   ref="selectUserDubboServiceImpl" group="dubbo" version="1.0.0" timeout="5000"/>

    <dubbo:service interface="com.bobo.dubbo.service.DeleteUserDubboService"
                   ref="deleteUserDubboServiceImpl" group="dubbo" version="1.0.0" timeout="5000"/>
</beans>
   
整个项目结构。

  
然后将dubbo-parent 打包处理,然后添加主方法,测试。
package com.bobo.dubbo;

import com.alibaba.dubbo.container.Main;


public class Start {
    public static void main(String[] args) throws Exception{
        // Dubbo提供的启动方法,默认会去classpath:/META-INF/spring/*.xml 加载
        Main.main(args);
    }
}
  

  
Zookeeper中查看的注册信息。

  
2.5 创建消费者
2.5.1 创建dubbo-user-consumer

  
2.5.2 创建service服务

  
修改pom文件。
    <dependencies>
        <!-- 添加对provide中的interface服务的依赖 -->
        <dependency>
            <groupId>com.bobo</groupId>
            <artifactId>dubbo-user-provider-interface</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
    </dependencies>
  
2.5.3 创建web服务

  
修改pom文件
<?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">
    <parent>
        <artifactId>dubbo-user-consumer</artifactId>
        <groupId>com.bobo</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>dubbo-user-consumer-web</artifactId>
    <packaging>war</packaging>

    <name>dubbo-user-consumer-web Maven Webapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

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

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.bobo</groupId>
            <artifactId>dubbo-user-consumer-web-service</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- dubbo的依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.5.3</version>
            <exclusions>
                <exclusion>
                    <groupId>spring</groupId>
                    <artifactId>org.springframework</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- Zookeeper的客户端 -->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <path>/</path>
                    <port>8082</port>
                </configuration>
            </plugin>
        </plugins>
        <finalName>dubbo-user-consumer-web</finalName>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.0</version>
                </plugin>
                <plugin>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.22.1</version>
                </plugin>
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>3.2.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-install-plugin</artifactId>
                    <version>2.5.2</version>
                </plugin>
                <plugin>
                    <artifactId>maven-deploy-plugin</artifactId>
                    <version>2.8.2</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>
    
添加相关的配置文件 SpringMVC,Spring,web.xml,Dubbo。
applicationContext-dubbo.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: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://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://code.alibabatech.com/schema/dubbo
    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 消费者应用信息 -->
    <dubbo:application name="dubboConsumer" />

    <!-- 配置和Provide相同的注册中心 -->
    <dubbo:registry protocol="zookeeper"
                    address="192.168.100.120:2181,192.168.100.121:2181,192.168.100.122:2181" />

    <!-- 订阅Dubbo中的服务 -->
    <dubbo:reference interface="com.bobo.dubbo.service.AddUserDubboService"
                     id="addUserDubboService" group="dubbo" version="1.0.0" timeout="5000"/>

    <dubbo:reference interface="com.bobo.dubbo.service.SelectUserDubboService"
                     id="selectUserDubboService" group="dubbo" version="1.0.0" timeout="5000"/>

    <dubbo:reference interface="com.bobo.dubbo.service.DeleteUserDubboService"
                     id="deleteUserDubboService" group="dubbo" version="1.0.0" timeout="5000"/>

</beans>
  
applicationContext-service.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:p="http://www.springframework.org/schema/p"
       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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 扫描bean对象 -->
    <context:component-scan base-package="com.bobo.service.impl"/>
</beans>
  
springmvc.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:p="http://www.springframework.org/schema/p"
       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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 包的扫描器主要是扫描@controller -->
    <context:component-scan base-package="com.bobo.controller" />

    <!-- 注册两个新对象 主要是为了来处理springmvc中的其他anntation 如:@requestmapping -->
    <mvc:annotation-driven />

    <!-- 视图解析器 -->
    <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- jsp所在的前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
    <!-- 配置静态资源映射 -->
    <mvc:resources location="/WEB-INF/css/" mapping="/css/**" />
    <mvc:resources location="/WEB-INF/js/" mapping="/js/**" />
</beans>
   
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_3_0.xsd"
         id="WebApp_ID" version="3.0">
  <!-- 上下文参数,告诉Spring配置文件路径 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext-*.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- 配置springmvc -->
  <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</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>

  <filter>
    <filter-name>encoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>


  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>
  

   
测试web项目是否可以访问。

  
访问成功。

  
3. 业务实现

  
3.1 添加用户信息
3.1.1 dubbo-mapper
package com.bobo.mapper;

import com.bobo.pojo.User;

/**
* UserMapper接口
*/
public interface UserMapper {
    int insertUser(User user);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD
Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.bobo.mapper.UserMapper">
    <insert id="insertUser" parameterType="com.bobo.pojo.User">
        insert into users(username,userage)values(#{username},#{userage})
    </insert>

</mapper>
  
3.1.2 dubbo-user-service-interface
在dubbo-user-service-interface中声明provider对外提供的功能。
package com.bobo.dubbo.service;

import com.bobo.pojo.User;

public interface AddUserDubboService {
    void addUser(User user);
}
  
3.1.3 dubbo-user-service
依赖
<dependencies>
    <dependency>
        <groupId>com.bobo</groupId>
        <artifactId>dubbo-user-provider-interface</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

    <dependency>
        <groupId>com.bobo</groupId>
        <artifactId>dubbo-mapper</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

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

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
    </dependency>

    <!-- dubbo的依赖 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>dubbo</artifactId>
        <version>2.5.3</version>
        <exclusions>
            <exclusion>
                <groupId>spring</groupId>
                <artifactId>org.springframework</artifactId>
            </exclusion>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- Zookeeper的客户端 -->
    <dependency>
        <groupId>com.github.sgroschupf</groupId>
        <artifactId>zkclient</artifactId>
        <version>0.1</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
    </dependency>

</dependencies>
  
实现provider对外提供的功能。
package com.bobo.dubbo.service.impl;

import com.bobo.dubbo.service.AddUserDubboService;
import com.bobo.mapper.UserMapper;
import com.bobo.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class AddUserDubboServiceImpl implements AddUserDubboService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public void addUser(User user) {
        userMapper.insertUser(user);
    }
}
  
添加了对外新增的功能,那么我们需要将这个功能注册到Zookeeper的注册中心中,所以我们需要修改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:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    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://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context.xsd
     http://code.alibabatech.com/schema/dubbo
     http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 导入Spring相关的配置文件 -->
    <import resource="../../applicationContext-dao.xml" />
    <import resource="../../applicationContext-service.xml" />
    <import resource="../../applicationContext-trans.xml" />
    <dubbo:application name="user-provider" />
    <dubbo:registry protocol="zookeeper"address="192.168.100.120:2181,192.168.100.121:2181,192.168.100.122:2181"/>
    <dubbo:protocol name="dubbo" port="20880"/>
    <!-- 添加向Zookeeper注册的服务 -->
    <dubbo:service interface="com.bobo.dubbo.service.AddUserDubboService"ref="addUserDubboServiceImpl"group="dubbo" version="1.0.0"timeout="5000"/>
</beans>
  
重启服务,然后去Zookeeper中查看相关的注册信息。

  
3.1.4 dubbo-user-web-service
public interface UserService {
    int addUser(User user);
}
  
创建接口的实现。
package com.bobo.service.impl;

import com.bobo.dubbo.service.AddUserDubboService;
import com.bobo.pojo.User;
import com.bobo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService{
    /**
    * 从Spring容器中获取 provider中的接口的代理对象
    */
    @Autowired
    public AddUserDubboService addUserDubboService;
    @Override
    public int addUser(User user) {
        addUserDubboService.addUser(user);
        return 1;
    }
}
   
3.1.5 dubbo-user-web
需要向dubbo订阅对应的服务。
<!-- 订阅Dubbo中的服务 -->
<dubbo:reference interface="com.bobo.dubbo.service.AddUserDubboService"
    id="addUserDubboService"
    group="dubbo" version="1.0.0" timeout="5000"
/>
  
添加新增用户的界面。
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
</head>
<body>
<form action="/user/addUser" method="post">
    用户名:<input type="text" name="username" /><br />
    用户年龄:<input type="text" name="userage" /><br />
    <input type="submit" value="提交" />
</form>
</body>
</html>
  

  
测试报错

  
pojo对象必须要实现序列化。

  
数据库中查看信息。

  
3.2 查询用户信息
mapper添加相关的信息。
在provider的接口中声明服务。
在provider中实现服务,并注册到注册中心。
消费者订阅服务,调用服务。
  
3.3 删除用户信息
mapper添加相关的信息。
在provider的接口中声明服务。
在provider中实现服务,并注册到注册中心。
消费者订阅服务,调用服务。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1369684.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JAVA】Java8开始ConcurrentHashMap,为什么舍弃分段锁

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 分段锁的好处&#xff1a; 结语 我的其他博客 前言 在Java 8中&#xff0c;ConcurrentHashMap的实现经历了重大的改进&am…

新AI图像分割方法GenSAM:一个提示实现批量图片分割

近期&#xff0c;研究人员提出了一种新型图像分割方法&#xff0c;称为Generalizable SAM&#xff08;GenSAM&#xff09;模型。该模型的设计目标是通过通用任务描述&#xff0c;实现对图像的有针对性分割&#xff0c;摆脱了对样本特定提示的依赖。在具体任务中&#xff0c;给定…

C# 强制类型转换和as区别和不同使用场景

文章目录 1.强制类型转换2. as 运算符3.实例总结&#xff1a; 在C#中&#xff0c;as 和 强制类型转换&#xff08;例如 (T)value&#xff09;的主要区别在于它们处理类型转换不成功时的行为和适用场景&#xff1a; 1.强制类型转换 使用语法&#xff1a;Type variable (Type)…

C语言深度剖析 -- 深度理解符号

文章目录 注释符号yx/*p条件编译 续行符与转义符 \回车与换行的区别 单引号与双引号逻辑运算符位运算符&、|、^整型提升问题左移 << 右移 >>花括号&#xff08;了解&#xff0c;不太推荐&#xff09;、-- 操作符 我们为什么要深入理解C语言中的符号呢&#xff…

JS入门笔记整理:函数

函数一般用来实现某种重复使用的功能&#xff0c;在需要使用该功能的时候&#xff0c;直接调用函数就可以了&#xff0c;不需要再重复地编写一大堆代码。并且在需要修改该函数功能的时候&#xff0c;也只需要修改和维护这一个函数就行。函数一般会在两种情况下使用&#xff1a;…

助力企业出海,Ogcloud提供一站式网络解决方案

随着全球市场的开放和跨境电商的蓬勃发展&#xff0c;越来越多企业开始在海外拓展业务。但在这过程中&#xff0c;各种各样的网络问题成为企业出海的阻碍。Ogcloud凭借其卓越的技术实力和丰富的经验&#xff0c;为全球业务的公司提供全面的网络解决方案&#xff0c;包括SD-WAN、…

文件或目录损坏的磁盘修复方法

文件或目录损坏是一种常见的计算机问题&#xff0c;可能由多种原因导致&#xff0c;如磁盘故障、病毒或恶意软件攻击、文件系统错误等。这些损坏可能导致数据丢失或无法访问文件&#xff0c;因此及时修复至关重要。本文将深入探讨文件或目录损坏的原因&#xff0c;并提供相应的…

Zookeeper的基础介绍和安装教程

1、 Zookeeper入门 1.1 概述 Zookeeper是一个开源的分布式的&#xff0c;为分布式应用提供协调服务的Apache项目。 1.2 特点 1.3 数据结构 1.4 应用场景 提供的服务包括&#xff1a;统一命名服务、统一配置管理、统一集群管理、服务器节点动态上下线、软负载均衡等。 统一…

编程基础 - 初识Linux

编程基础 - 初识Linux 返回序言及专栏目录 文章目录 编程基础 - 初识Linux前言一、Linux发展简介二、现代Linux三、Linux系统各发行版小结 前言 为什么要学习Linux呢&#xff1f;我这Windows用得好好的&#xff0c;简单易用傻瓜式、用的人还超多&#xff01;但是我要告诉你的…

解决word图片格式错乱、回车图片不跟着换行的问题

解决word图片格式错乱、回车图片不跟着换行的问题 1.解决方法。 先设置为嵌入型 但是设置的话会出现下面的问题。图片显示不全。 进一步设置对应的行间距&#xff0c;原先设置的是固定值&#xff0c;需要改为1.5倍行距的形式&#xff0c;也就是说不能设置成固定值就可以。

mybatisplus快速入门-个人理解版

mybatisplus快速入门 1.快速入门1.1准备开发环境-idea2019.2.1版第一步&#xff1a;新建工程第二步&#xff1a;导入依赖 1.2创建数据库和表创建库表添加数据 1.3编写代码进行测试第一步&#xff1a;配置application.yml第二步&#xff1a;添加实体类第三步&#xff1a;添加map…

让开发改bug全靠催?分享6个实用技巧

测试小伙伴们&#xff0c;你们有遇到下图的情况吗&#xff1f; ​ 这张图其实还算“温柔”的&#xff0c;其实有些情况下&#xff0c;某些测试人员或者开发人员脾气大的可能撕逼或者快干架。所以如何和开发有效沟通&#xff0c;并高效劝说开发改掉bug是一门学问&#xff0c;以…

手拉手springboot3整合mybatis-plus多数据源

环境介绍 技术栈 springbootmybatis-plusmysql 软件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 17 Spring Boot 3.1.7 dynamic-datasource 3.6.1 mybatis-plus 3.5.3.2 加入依赖 <dependency><groupId>com.baomidou</groupId><arti…

softmax详解

在神经网络中&#xff0c;Softmax 是一个用于多类别分类的激活函数。给定一个包含原始分数&#xff08;未经处理的模型输出&#xff09;的向量&#xff0c;Softmax 将这些分数转化为表示概率分布的向量。具体而言&#xff0c;对于给定的原始分数向量 ( z )&#xff0c;Softmax …

STM32-03-STM32HAL库

文章目录 STM32HAL库1. HAL库介绍2. STM32Cube固件包3. HAL库框架结构4. 新建HAL版本MDK工程 STM32HAL库 1. HAL库介绍 HAL库 HAL&#xff0c;英文全称 Hardware Abstraction Layer&#xff0c;即硬件抽象层。HAL库是ST公司提供的外设驱动代码的驱动库&#xff0c;用户只需要调…

CentOS找回root密码

很悲伤&#xff0c;你忘记了root密码。。。 那就来重置它吧~ 1、在启动时选择操作系统&#xff1a;在引导过程中&#xff0c;选择CentOS操作系统并按下键盘上的任意键来停止引导。 2、 进入编辑模式&#xff1a;在启动菜单中&#xff0c;找到并选择要编辑的CentOS条目&…

科锐16位汇编学习笔记 04 乘除和移位指令

乘法和除法指令用的不多,因为效率很低 比较指令CMP (compare) •格式&#xff1a;CMP OPD&#xff0c;OPS •功能&#xff1a;(OPD) — (OPS),跟减法指令很像,但是不存结果 •说明&#xff1a;目的操作数减去源操作数&#xff0c;然后根据结果设置标志位&#xff0c;但该结…

Hyperledger Fabric 通道配置文件解析

fabric 版本 v2.4.1 Fabric 网络是分布式系统&#xff0c;采用通道配置&#xff08;Channel Configuration&#xff09;来定义共享账本的各项行为。通道配置的管理对于网络功能至关重要。 通道配置一般包括通道全局配置、排序配置和应用配置等多个层级&#xff0c;这些配置都存…

红队打靶练习:RICKDICULOUSLYEASY: 1

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 目录探测 gobuster dirsearch WEB get flag1 /robots.txt FTP get flag2 telenet登录 get flag3 get flag4 9090端口 get flag5 dirsearch ssh登录 Summer用户 get flag6 信息收集 get flag7 get fl…

学习笔记之——3D Gaussian Splatting及其在SLAM与自动驾驶上的应用调研

之前博客介绍了NeRF-SLAM&#xff0c;其中对于3D Gaussian Splatting没有太深入介绍。本博文对3D Gaussian Splatting相关的一些工作做调研。 学习笔记之——NeRF SLAM&#xff08;基于神经辐射场的SLAM&#xff09;-CSDN博客文章浏览阅读967次&#xff0c;点赞22次&#xff0…