天天看点

Dubbo-zookeeper(注册中心)

5 使用注册中心

Dubbo目前支持4种注册中心,(multicast、zookeeper、redis、simple) ,推荐使用Zookeeper注册中心。

Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,因此被dubbo并推荐使用。

  • 当提供者出现断电等异常停机时,注册中心能自动删除提供者信息
  • 当注册中心重启时,能自动恢复注册数据,以及订阅请求
  • 当会话过期时,能自动恢复注册数据,以及订阅请求
  • 当设置

    <dubbo:registry check="false" />

    时,记录失败注册和订阅请求,后台定时重试
  • 可通过

    <dubbo:registry username="admin" password="1234" />

    设置 zookeeper 登录信息
  • 可通过

    <dubbo:registry group="dubbo" />

    设置 zookeeper 的根节点,不设置将使用无根树
  • 支持

    *

    号通配符

    <dubbo:reference group="*" version="*" />

    ,可订阅服务的所有分组和所有版本的提供者

5.1 安装zookeeper注册中心

(1)Zookeeper官网:https://zookeeper.apache.org/

(2)下载并解压 “apache-zookeeper-3.5.6-bin.tar.gz”

(3)修改配置文件(~/config/zoo.cfg)

复制“~/config/zoo_sample.cfg”文件副本并改名为“zoo.cfg”,修改其中的“dataDir”(数据文件路径)和“admin.serverPort”(内置的Jetty服务器监听的端口。默认是8080 ),保存。

Dubbo-zookeeper(注册中心)

(4)启动(~/bin/zkServer.cmd)

Dubbo-zookeeper(注册中心)

5.2 使用 zookeeper 作为 dubbo 注册中心

5.2.1 创建服务抽象层(006-zk-interface)87

5.2.2 创建服务提供者(007-zk-userservice-provider)

(1)添加依赖(除了 spring、springmvc、dubbo、接口中间层依赖外,需要额外添加 zookeeper 注册中心依赖)

<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>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.9.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>4.3.9.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version>2.6.2</version>
        </dependency>
        <dependency>
          <groupId>samchen.dubbo</groupId>
          <artifactId>006-zk-interface</artifactId>
          <version>1.0.0</version>
        </dependency>
        <!--zookeeper依赖-->
        <dependency>
          <groupId>org.apache.curator</groupId>
          <artifactId>curator-framework</artifactId>
          <version>4.1.0</version>
        </dependency>
	</dependencies>
           

(2)实现业务接口

(3)配置 dubbo 服务提供者(dubbo-zk-userservice-provider.xml)

​ 添加<dubbo:registry … /> 配置,去掉原来 <dubbo:service /> 中的“registry=“N/A””。

<?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="007-zk-userservice-provider" />
    <!--声明dubbo使用的协议和端口号-->
    <dubbo:protocol name="dubbo" port="20880"/>
    <!--*** 指定注册中心地址和端口号 (增加)*** zookeeper代表协议-->
    <dubbo:registry address="zookeeper://localhost:2181" />
    <!--暴露服务接口 (去掉原来的registry="N/A")-->
    <dubbo:service interface="com.bjpowernode.service.UserService" ref="userService"/>
    <!--托管服务实现类-->
    <bean id="userService" class="com.bjpowernode.service.UserServiceImpl" />
</beans>
           

(4)配置web服务器(web.xml)

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:dubbo-zk-provider.xml</param-value>
  </context-param>
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener
      </listener-class>
  </listener>
</web-app>
           

5.2.3 配置服务消费者(008-zk-consumer)

(1)添加依赖

<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>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>dubbo</artifactId>
      <version>2.6.2</version>
    </dependency>
    <dependency>
      <groupId>samchen.dubbo</groupId>
      <artifactId>006-zk-interface</artifactId>
      <version>1.0.0</version>
    </dependency>
    <!--zookeeper注册中心依赖-->
    <dependency>
      <groupId>org.apache.curator</groupId>
      <artifactId>curator-framework</artifactId>
      <version>4.1.0</version>
    </dependency>
           

(2)配置 dubbo 消费者

添加<dubbo:registry … /> 配置,去掉原来 中的“registry=“N/A”” 和 “url=“…””

<?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="008-zk-userserivce-consumer"/>
    <!--*** 指定注册中心 ***-->
    <dubbo:registry address="zookeeper://localhost:2181" />
    <!--引用远程接口服务(去掉原来的 registry="N/A" 和 url="...")-->
    <dubbo:reference id="userService" interface="com.bjpowernode.service.UserService" />
</beans>
           

(3)配置mvc

<?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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
    <!--扫描包-->
    <context:component-scan base-package="com.bjpowernode.web"/>
    <mvc:annotation-driven/>
    <!--jsp视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
           

(4)配置 web 服务器web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:dubbo-zk-consumer.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <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:spring-mvc.xml</param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

           

5.2.4 启动

(1)优先启动 zookeeper

(2)然后启动服务提供者

(3)最后启动服务消费者

6 版本号的使用

dubbo允许在接口实现更新时保留旧的服务实现,添加新的服务实现,只要通过版本号来标识暴露的服务即可。

6.1 在服务提供者中指定版本

(1)新建服务提供者(009-zk-multi-userservice-provider),添加一个新的服务接口实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bsbrdUuO-1666011084676)(dubbo.assets/image-20210424222416577.png)]

(2)配置服务提供者(dubbo-zk-multi-userservice-provider.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo 
http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
    <!--声明dubbo服务提供程序名称,确保唯一性-->
    <dubbo:application name="009-zk-userservice-provider" />
    <!--声明dubbo使用的协议和端口号-->
    <dubbo:protocol name="dubbo" port="20880"/>
    <!--*** 指定注册中心地址和端口号 (增加)***-->
    <dubbo:registry  address="zookeeper://localhost:2181" />
    <!--暴露服务接口 (去掉原来的registry="N/A")-->
    <dubbo:service interface="com.bjpowernode.service.UserService" ref="userService" version="1.0.0"/>
    <dubbo:service interface="com.bjpowernode.service.UserService" ref="userService2" version="2.0.0"/>
    <!--托管服务实现类-->
    <bean id="userService" class="com.bjpowernode.service.UserServiceImpl" />
    <bean id="userService2" class="com.bjpowernode.service.UserServiceImpl2" />
</beans>
           

6.2 在服务消费者中指定版本号

(1)配置消费者声明服务引用,指定版本号

<?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消费者名称,保证唯一性 -->
    <dubbo:application name="010-zk-userserivce-consumer"/>
    <!--*** 指定注册中心 ***-->
    <dubbo:registry address="zookeeper://localhost:2181"/>
    <!--引用远程接口服务(同一个接口有多个实现类,需要用version区分)-->
    <dubbo:reference id="userService1" interface="com.bjpowernode.service.UserService" version="1.0.0" />
    <dubbo:reference id="userService2" interface="com.bjpowernode.service.UserService" version="2.0.0" />
</beans>
           

(2)根据不同的 服务id 调用不同的服务实现

@Controller
public class IndexController {
    @Autowired
    private UserService userService1;
    @Autowired
    private UserService userService2;

    @RequestMapping("/index")
    public String index(Model model){
        model.addAttribute("user1",userService1.queryByUserId(1));
        model.addAttribute("user2",userService2.queryByUserId(1));
        return "index";
    }
}
           

7 Dubbo监控中心

阿里为方便管理人员可视化的维护dubbo服务,提供了一个dubbo管理程序,这是一个基于SpringBoot的工程。

使用者可以下载该项目:

https://github.com/apache/incubator-dubbo-ops

解压后可以根据情况修改信息( application.properties)并将源码编译打包生成jar运行使用。

进入 dubbo-admin 项目(管理控制台)

1) 修改dubbo-admin配置文件中zookeeper的注册地址(配置信息在application.properties文件)

2) 使用mvn clean package 命令进行打包

3)使用java -jar dubbo-admin-0.0.1-SNAPSHOT.jar命令运行

4)访问http://localhost:7001 
   账号:root  密码:root 
           
Dubbo-zookeeper(注册中心)

8 Dubbo负载均衡

Dubbo是一个分布式服务框架,能避免单点故障和支持服务的横向扩容。一个服务通常会部署多个实例。如何从多个服务 Provider 组成的集群中挑选出一个进行调用,就涉及到一个负载均衡的策略。

8.1 Dubbo内置负载均衡策略

Dubbo内置了4种负载均衡策略:

  1. RandomLoadBalance:随机负载均衡。随机的选择一个。是Dubbo的默认负载均衡策略。
  2. RoundRobinLoadBalance:轮询负载均衡,所有的提供者一个一个轮询选择。
  3. LeastActiveLoadBalance:最少活跃调用数,相同活跃数的随机。活跃数指调用前后计数差。使慢的 Provider 收到更少请求,因为越慢的 Provider 的调用前后计数差会越大。
  4. ConsistentHashLoadBalance:一致性哈希负载均衡。相同参数的请求总是落在同一台机器上。

8.2 模拟多个提供者,测试“轮询负载”均衡

(1)将提供者项目,复制一份,更名为“011-zk-multi-userservice-se”,改变端口

第一个提供者配置端口

<dubbo:application name="009-zk-multi-userservice" />
<!--声明dubbo使用的协议和端口号-->
<dubbo:protocol name="dubbo" port="20880"/>
           

第二个提供者配置端口

<dubbo:application name="011-zk-multi-userservice-se" />
<!--声明dubbo使用的协议和端口号-->
<dubbo:protocol name="dubbo" port="20881"/>
           

(2)轮询策略

(3)设置随机的权重策略

修改权重----每个服务权重默认为100,越大几率越高

(4)最少活跃策略leastactive

最少活跃调用数表示为服务器节点处理接口的能力,处理接口约耗时则活跃数约小,系统会使慢的节点约少接收到请求。配置方式loadbalance=“leastactive”。(使用最小活跃调用数时,不要配置权重不然失去了该模式意义)当启动两个服务后通过接口中睡眠时间来模拟接口处理能力,通过控制台可以看到睡眠时间越小的节点获取的请求越多。耗时越久的接收的请求越小

(5)一致性Hash模式策略

一致性hash模式表示相同接口相同参数的请求将固定发送到某一个节点。在Service注解中使用**loadbalance=“consistenthash”**进行设置。

有时候服务停止了,但是dubbo-admin还显示有,即使服务停止了,也会自动从缓存中获取服务提供数据.

8.3 check属性

Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true。

​ 如果你的Spring容器是懒加载的,或者通过API编程延迟引用服务,请关闭check,否则服务临时不可用时,会抛出异常,拿到null引用,如果check=false,总是会返回引用,当服务恢复时,能自动连上。

​ 可以通过check="false"关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。

9 附录:相关配置汇总

9.1 服务接口层

(1)pom.xml(仅jdk编译版本设定,无需其它依赖)

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
           

(2)实体类

import java.io.Serializable;
//必须是可序列化类才能被dubbo传输
public class User implements Serializable {
    private int id;
    private String username;
    private String password;
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
    @Override
    public String toString() {
        return "User{ id=" + id + ", username='" + username + '\'' +", password='" + password + '\'' +'}';
    }
}
           

(3)业务接口

public interface UserService {
    User queryUserById(Integer id);
}
           

9.2 服务提供者

(1)pom.xml(springmvc、dubbo、zookeeper)

<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>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.9.RELEASE</version>
        </dependency>
        <!-- dubbo 依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.6.2</version>
        </dependency>
        <!--zookeeper注册中心依赖-->
        <dependency>
          	<groupId>org.apache.curator</groupId>
          	<artifactId>curator-framework</artifactId>
          	<version>4.1.0</version>
        </dependency>
        <!--这里还需要配置:服务接口层依赖-->
    </dependencies>
           

(2)业务实现类:

public class UserServiceImipl implements UserService {
    @Override
    public User queryUserById(Integer id) {
        User user = new User();
        user.setId(1003);
        user.setUsername("wangwu");
        user.setPassword("123456");
        return user;
    }
}
           

(3)spring dubbo配置(dubbo-userservice-provider.xml)

dubbo直连版本:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       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="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />
    <!-- 配置协议和端口(dubbo官方推荐使用dubbo协议,端口好默认20880)
        name:服务协议的名称、
        port:端口号 -->
    <dubbo:protocol name="dubbo" port="20880" />
    <!-- 暴露服务接口
        interface:暴露服务接口类名
        ref:接口引用的实现类在Spring容器中的标识
        registry:注册中心,若不使用(直连),则值为:N/A -->
    <dubbo:service interface="com.bjpowernode.service.UserService" ref="userService" registry="N/A"/>
    <!-- 接口实现类加载到Spring容器 -->
    <bean id="userService" class="com.bjpowernode.service.UserServiceImpl" />
</beans>
           

zookeeper注册中心版本:

<?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="007-zk-userservice-provider" />
    <!--声明dubbo使用的协议和端口号-->
    <dubbo:protocol name="dubbo" port="20880" />
    <!--*** 指定注册中心地址和端口号 (增加)*** zookeeper代表协议-->
    <dubbo:registry address="zookeeper://localhost:2181" />
    <!--暴露服务接口 (去掉原来的registry="N/A")-->
    <dubbo:service interface="com.bjpowernode.service.UserService" ref="userService" />
    <!--托管服务实现类对象-->
    <bean id="userService" class="com.bjpowernode.service.UserServiceImipl" />
</beans>
           

(5)spring监听器配置(web.xml)

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:/dubbo-userservice-provider.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>
           

9.3 服务消费者

(1)pom.xml (略:与服务提供者配置相同)

(2)spring dubbo配置(dubbo-consumer.xml)

dubbo直连版本:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
       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" />
    <!--服务引用- N/A表示直连,不需要注册中心-->
    <dubbo:reference id="userService"
            interface="com.bjpowernode.service.UserService"
            url="dubbo://localhost:20880" registry="N/A"/>
</beans>
           

zookeeper注册中心版本:

<?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="008-zk-consumer" />
    <!--*** 指定注册中心 ***-->
    <dubbo:registry address="zookeeper://localhost:2181" />
    <!--引用远程接口服务(去掉原来的 registry="N/A" 和 url="...")-->
    <dubbo:reference id="userService" interface="com.bjpowernode.service.UserService" />
</beans>
           

(3)spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
    <!--扫描包-->
    <context:component-scan base-package="com.bjpowernode.web"/>
    <!--注解驱动-->
    <mvc:annotation-driven/>
    <!--jsp视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
           

(4)springmvc核心控制器(web.xml)

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <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:spring-mvc.xml,classpath:dubbo-consumer.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
           

(5)控制器IndexController(调用服务提供者)

@Controller
public class IndexController {
    @Autowired
    private UserService userService;
    @RequestMapping("/index")
    public String index(Model model){
        model.addAttribute("user",userService.queryUserById(1));
        return "index";
    }
}
           

(6)jsp页面(显示调用服务结果)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>服务消费者</h1>
    <h2>${user}</h2>
</body>
</html>
           
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<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:spring-mvc.xml,classpath:dubbo-consumer.xml</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
           

```

(5)控制器IndexController(调用服务提供者)

@Controller
public class IndexController {
    @Autowired
    private UserService userService;
    @RequestMapping("/index")
    public String index(Model model){
        model.addAttribute("user",userService.queryUserById(1));
        return "index";
    }
}
           

(6)jsp页面(显示调用服务结果)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>服务消费者</h1>
    <h2>${user}</h2>
</body>
</html>