DUBBO应用

1.现状———解决方案

在大规模服务化之前,应用可能只是通过RMI或Hessian等工具,简单的暴露和引用远程服务,通过配置服务的URL地址进行调用,通过F5等硬件进行负载均衡。
(1) 当服务越来越多时,服务URL配置管理变得非常困难,F5硬件负载均衡器的单点压力也越来越大。
此时需要一个服务注册中心,动态的注册和发现服务,使服务的位置透明。
并通过在消费方获取服务提供方地址列表,实现软负载均衡和Failover,降低对F5硬件负载均衡器的依赖,也能减少部分成本。

(2) 当进一步发展,服务间依赖关系变得错踪复杂,甚至分不清哪个应用要在哪个应用之前启动,架构师都不能完整的描述?

(3) 接着,服务的调用量越来越大,服务的容量问题就暴露出来,这个服务需要多少机器支撑?什么时候该加机器?
为了解决这些问题,第一步,要将服务现在每天的调用量,响应时间,都统计出来,作为容量规划的参考指标。
其次,要可以动态调整权重,在线上,将某台机器的权重一直加大,并在加大的过程中记录响应时间的变化,直到响应时间到达阀值,记录此时的访问量,再以此访问量乘以机器数反推总容量。

简介

Dubbo是什么
一个分布式高性能RPC服务框架,SOA治理方案.

核心功能
A.远程通讯
–多协议集成,提供对多种基于长连接的NIO框架抽象封装
B.集群容错
–失败自动切换,当出现失败,重试其它服务器。(缺省)
C.自动发现
–基于注册中心目录服务,使服务消费方能动态的查找服务提供方,使地址透明,使服务提供方可以平滑增加或减少机器。
D.软负载均衡
–可在内网替代F5等硬件负载均衡器,降低成本,减少单点

DUBBO架构展示

节点角色说明:
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器

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

Dubbo模块详解:

服务定义服务是围绕服务提供方和服务消费方的,服务提供方实现服务,而服务消费方调用服务。

服务注册对于服务提供方,它需要发布服务,而且由于应用系统的复杂性,服务的数量、类型也不断膨胀;对于服务消费方,它最关心如何获取到它所需要的服务,而面对复 杂的应用系统,需要管理大量的服务调用。而且,对于服务提供方和服务消费方来说,他们还有可能兼具这两种角色,即既需要提供服务,有需要消费服务。通过将服务统一管理起来,可以有效地优化内部应用对服务发布/使用的流程和管理。服务注册中心可以通过特定协议来完成服务对外的统一。Dubbo提供的注册中心有如下几种类型可供选择:
Multicast注册中心
Zookeeper注册中心
Redis注册中心
Simple注册中心

服务监控无论是服务提供方,还是服务消费方,他们都需要对服务调用的实际状态进行有效的监控,从而改进服务质量

协议支持Dubbo支持多种协议,如下所示:
Dubbo协议
Hessian协议
HTTP协议
RMI协议
WebService协议
Thrift协议
Memcached协议
Redis协议
在通信过程中,不同的服务等级一般对应着不同的服务质量,那么选择合适的协议便是一件非常重要的事情。你可以根据你应用的创建来选择。例如,使用 RMI协议,一般会受到防火墙的限制,所以对于外部与内部进行通信的场景,就不要使用RMI协议,而是基于HTTP协议或者Hessian协议。

DUBBO配置

1.服务提供者暴露服务配置
Ref: 服务对象实现引用 interface: 服务接口名

2.服务消费者引用服务配置
Interface: 服务接口名 id: 服务引用BeanId

3.服务提供者协议配置
Name:协议名称(默认是dubbo协议)hession,http.,webService,rmi

4.注册中心配置
Port:dubbo协议缺省端口为20880,rmi协议缺省端口为1099,http和hessian协议缺省端口为80
Host: 自动查找本机IP

5.监控中心配置
监控中心协议,如果为protocol=”registry”,表示从注册中心发现监控中心地址,否则直连监控中心否则直连监控中心服务器地址,address=”10.20.130.230:12080“

6.模块信息配置
Name: 当前模块名称,用于注册中心计算模块间依赖关系

7.应用信息配置
Name:当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样,此参数不是匹配条件, 你当前项目叫什么名字就填什么,和提供者消费者角色无关,比如:kylin应用调用了morgan应用的服务,则kylin项目配成 kylin,morgan项目配成morgan,可能kylin也提供其它服务给别人使用,但kylin项目永远配成kylin,这样注册中心将显示 kylin依赖于morgan

8.服务提供者默认值配置,说明:该标签为和标签的默认设置。
Id: 协议BeanId,可以在中引用此ID
Protocol:协议名称

9.服务消费者默认值配置, 该标签为标签的缺省值设置

  1. 方法级配置, 该标签为或的子标签,用于控制到方法级
    Name:方法名

  2. 方法参数配置, 该标签为的子标签,用于方法参数的特征描述



    Index: int值方法名
    Callback:布尔值参数是否为callback接口,如果为callback,服务提供方将生成反向代理,可以从服务提供方反向调用消费方,通常用于事件推送.

DUBBO依赖

<project>
  <dependencies>
      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>dubbo</artifactId>
          <version> 2.4.9/version>
      </dependency>
   </dependencies>
</project>
    在阿里巴巴内部广泛使用的GA版本为:2.4.9

DUBBO简单实例

服务接口:


import java.util.List;

import com.deppon.gis.common.pojo.User;

public interface UserService {

    public List<User> queryAll();
}

dubbo传输对象实体类(必须实现序列化接口)


import java.io.Serializable;

// 使用dubbo要求传输的对象必须实现序列化接口
public class User implements Serializable {

    private static final long serialVersionUID = -7341603933521593227L;

    private Long id;

    private String username;

    private String password;

    private Integer age;

    public Long getId() {
        return id;
    }

    public void setId(Long 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;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password="
                + password + ", age=" + age + "]";
    }


}

服务提供方Spring核心配置文件以及代码实现

<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" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    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://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="dubbo-provider" />

    <!-- 这里使用的注册中心是zookeeper -->
    <dubbo:registry address="zookeeper://10.230.13.74:2181"
        client="zkclient" />

    <!-- 用dubbo协议在20880端口暴露服务   port="20880"-->
    <dubbo:protocol name="dubbo"   port="20880"/>

    <!-- 将该接口暴露到dubbo中 -->
    <dubbo:service interface="com.deppon.gis.common.service.UserService"
        ref="userServiceImpl" />
     <!-- 服务提供方    interface:服务接口名  version:版本号(注意只有在版本号一致的情况下,才可以完成消费端到提供端的调用)
     cluster:集群容错模式   retries:远程服务调用重试次数,不包括第一次调用   timeout:服务方法调用超时时间 
     protocol:只调用指定协议的服务提供方     dubbo:method会继承dubbo:service中配置的属性   loadbalance:负载均衡策略-->
    <dubbo:service interface="com.deppon.gis.common.service.UserService"
         cluster="failover"  ref="userServiceImpl"  loadbalance="random">
         <!-- <dubbo:method name="queryAll" timeout="80" retries="2" loadbalance="leastactive" /> -->
    </dubbo:service>
    <!-- 将具体的实现类加入到Spring容器中 -->
    <bean id="userServiceImpl" class="com.deppon.gis.provider.service.impl.UserServiceImpl" />
    <!-- 监控中心配置 -->
    <dubbo:monitor protocol="registry"/>


</beans>

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import com.deppon.gis.common.pojo.User;
import com.deppon.gis.common.service.UserService;


public class UserServiceImpl implements UserService{

    public List<User> queryAll() {
        long x=0;
        List<User> users=new ArrayList<User>();
        try {
             InetAddress addr = null;
               try {
                  addr = InetAddress.getLocalHost();
               } catch (UnknownHostException e) {
                  e.printStackTrace();
               }
               String IP=addr.getHostAddress().toString();
            for (int i = 0; i < 20; i++) {
                x++;
                User user= new User();
                user.setAge(i);
                user.setId(x);
                user.setPassword("MIMA"+i);
                user.setUsername("用户名"+IP+"--------线程名称"+Thread.currentThread().getName());
                users.add(user);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return users;
    }

}

服务消费方spring核心配置文件以及代码实现

<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" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    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://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">

    <!-- 提供方应用信息,用于计算依赖关系 -->
    <dubbo:application name="dubbo-consumer" />

    <!-- 这里使用的注册中心是zookeeper -->
    <dubbo:registry address="zookeeper://10.230.13.74:2181"
        client="zkclient" />

    <!-- 从注册中心中查找服务 -->
    <dubbo:reference id="userService"
        interface="com.deppon.gis.common.service.UserService" >
         <!-- <dubbo:method name="queryAll" retries="2" /> -->
    </dubbo:reference>

    <!-- 监控中心配置 -->

    <dubbo:monitor protocol="registry"/>

    <bean id="conSumer" class="com.deppon.gis.consumer.ConSumer">
       <property name="userService" ref="userService"></property>
    </bean>
</beans>


import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogConfigurationException;
import org.apache.commons.logging.LogFactory;

import com.alibaba.fastjson.JSON;
import com.deppon.gis.common.pojo.User;
import com.deppon.gis.common.service.UserService;

public class ConSumer {
    private static  Log log=LogFactory.getLog(ConSumer.class);
    private UserService userService;

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void queryAll(){
        List<User> queryAll = userService.queryAll();
        if(queryAll==null &&queryAll.size()==0){
            log.info("info级别 获取的数据为0");
            System.out.println("获取数据为0----------------------------");
        }
        for (User user : queryAll) {
            if(user==null){
                log.error("error级别 获取的数据为空");
                System.out.println("获取数据空----------------------------");
            }else{
            Object json = JSON.toJSON(user);
            System.out.println("阿里的fastjson,单独解析json对象"+json);
            }
        }
    }


}

DUBBO实例运行
这里写图片描述

Dubbo复杂配置

A.Dubbo服务集群容错配置
假设我们使用的是单机模式的Dubbo服务,如果在服务提供方(Provider)发布服务以后,服务消费方(Consumer)发出一次调用请求,恰好 这次由于网络问题调用失败,那么我们可以配置服务消费方重试策略,可能消费方第二次重试调用是成功的(重试策略只需要配置即可,重试过程是透明的);但 是,如果服务提供方发布服务所在的节点发生故障,那么消费方再怎么重试调用都是失败的,所以我们需要采用集群容错模式,这样如果单个服务节点因故障无法提 供服务,还可以根据配置的集群容错模式,调用其他可用的服务节点,这就提高了服务的可用性。
Dubbo内置支持如下6种集群模式:
Failover Cluster模式:
配置值为failover。这种模式是Dubbo集群容错默认的模式选择,调用失败时,会自动切换,重新尝试调用其他节点上可用的服务
**这里写图片描述**
如果调用失败一次,可以再次重试2次调用,服务级别调用超时时间为100ms,调用方法queryRoomUserCount的超时时间为80ms,允许重试2次,最坏情况调用花费时间160ms。
Failfast Cluster模式
配置值为failfast。这种模式称为快速失败模式,调用只执行一次,失败则立即报错。
Failsafe Cluster模式:
配置值为failsafe。失败安全模式,如果调用失败, 则直接忽略失败的调用,而是要记录下失败的调用到日志文件,以便后续审计

Failback Cluster模式
配置值为failback。失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作

Forking Cluster模式
配置值为forking。并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。

Broadcast Cluster模式
配置值为broadcast。广播调用所有提供者,逐个调用,任意一台报错则报错(2.1.0开始支持)。通常用于通知所有提供者更新缓存或日志等本地资源信息。

B.Dubbo服务负载均衡
Dubbo框架内置提供了4种负载均衡策略:
Random LoadBalance:随机策略,配置值为random。可以设置权重,有利于充分利用服务器的资源,高配的可以设置权重大一些,低配的可以稍微小一些(默认)
RoundRobin LoadBalance:轮询策略,配置值为roundrobin
LeastActive LoadBalance:配置值为leastactive。根据请求调用的次数计数,处理请求更慢的节点会受到更少的请求
ConsistentHash LoadBalance: ” 一致性Hash,相同参数的请求总是发到同一提供者。
” 当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。

这里写图片描述

此配置负载策略为:随机策略,dubbo:method配置负载策略为轮训策略,service默认策略为随机策略 methos如不定义随机策略,默认继承service负载策略

Dubbo管理控制台,简易控制中心的安装

1. Dubbo管理控制平台安装
作用:Dubbo的管理控制台,在实际的项目中非常的有用,尤其是在dubbo服务提供数量逐渐加大的情况下,通过Dubbo管理控制台能够很好的被我们所用,从而让我们更好的使用Dubbo提供的服务.
操作步骤:
A.Dubbo.properties配置文件管理注册中心连接以及管理控制平台用户名和密码
dubbo.registry.address=zookeeper://10.230.13.74:2181配置Zookeeper注册中心的地址和端口,这个属性支持多个注册中心的配置
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest以上两个属性是管理控制台的用户名密码.
这里写图片描述

B.启动服务
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

2.Dubbo 简易监控中心
dubbo-monitor作用:
Simple Monitor挂掉不会影响到Consumer和Provider之间的调用,所以用于生产环境不会有风险。

配置好了之后可以结合admin管理后台使用,可以清晰的看到服务的访问记录、成功次数、失败次数等…..

Simple Monitor采用磁盘存储统计信息,请注意安装机器的磁盘限制,如果要集群,建议用mount共享磁盘。
charts目录必须放在jetty.directory下,否则页面上访问不了

操作步骤
需要在服务端以及消费端dubbo核心配置文件中配置监控中心

服务端客户端监控中心配置:
这里写图片描述

启动Dubbo-monitor监控中心
这里写图片描述
因为dubbo监控中心内嵌jetty服务器,启动服务器,访问ip+8080路径
这里写图片描述
这里写图片描述

Dubbo管理SOA服务方案:

1.WebService
A.maven依赖

<dependencies>
        <!-- dubbo推荐版本2.4.9 阿里巴巴内部广泛使用的GA版本-->
       <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.4.9</version>
            <exclusions>
                <exclusion>
                    <!-- 排除传递spring依赖 -->
                    <artifactId>spring</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
            </exclusions>
       </dependency>
      <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.1.39</version>
        </dependency>
        <dependency>
           <groupId>gis.deppon.com</groupId>
           <artifactId>dubbo-api</artifactId>
           <version>0.0.1-SNAPSHOT</version>
        </dependency>
         <dependency>
           <groupId>org.codehaus.jackson</groupId>
           <artifactId>jackson-mapper-asl</artifactId>
           <version>1.9.4</version>
     </dependency>
   <dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-simple</artifactId>
    <version>2.6.1</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>2.6.1</version>
</dependency>
  </dependencies>

B.服务端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_2_5.xsd"
    id="WebApp_ID" version="2.5">

    <display-name>dubbo</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dubbo/dubbo-*.xml</param-value>
    </context-param>

    <!--Spring的ApplicationContext 载入 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

     <!--dubbo 服务根路径-->
    <servlet>
        <servlet-name>dubbo</servlet-name>
        <servlet-class>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dubbo</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
</web-app>

C.服务端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:application name="dubbo-webservice-app" />

    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://10.230.13.74:2181" />

    <!-- 用webservice协议在8080端口暴露服务,如server属性定义servlet,则暴露端口号必须与所在服务的端口号保持一致 -->
    <dubbo:protocol name="webservice" port="8080" server="servlet" />
    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.gis.webservice.service.DubboService"
        ref="dubboService" />

    <!-- 和本地bean一样实现服务 -->
    <bean id="dubboService" class="com.gis.webservice.service.impl.DubboServiceImpl" />

</beans>

//接口
public interface DubboService {

    public String printWord(String word);
}
//实现类
import com.gis.webservice.service.DubboService;

public class DubboServiceImpl implements DubboService {

    public String printWord(String word) {

        return "DUBBO 集成webService  返回字符串";
    }

}

D.客户端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:application name="dubbo-webservice-consumer" />

    <!-- 使用zookeeper注册中心暴露服务地址 -->
    <dubbo:registry address="zookeeper://10.230.13.74:2181" />

<!--URL属性:服务端服务的访问路径,最后路径则为接口的全路径 -->
   <dubbo:reference id="dubboService" interface="com.gis.webservice.service.DubboService"
    url="webservice://localhost:8080/services/com.gis.webservice.service.DubboService" />

    <bean id="consumerService" class="com.gis.consumer.service.impl.ConsumerServiceImpl">
        <property name="dubboService" ref="dubboService"></property>
    </bean>
</beans>

//代码实现
import com.gis.consumer.service.ConsumerService;
import com.gis.webservice.service.DubboService;

public class ConsumerServiceImpl implements ConsumerService {

    private DubboService dubboService;

    public void setDubboService(DubboService dubboService) {
        this.dubboService = dubboService;
    }

    public void say() {
        String printWord = dubboService.printWord("123");
        System.out.println("WebService客户端展示"+printWord);

    }


}

操作步骤:启动服务端以及客户端服务,输入服务访问路径判断webService服务是否搭建成功。如图展示如出现以下内容即表示webService服务搭建成功
测试结果展示:
这里写图片描述
这里写图片描述

2.restfulWebService
简介:Dubbox是Dubbo的一个扩展,功能展示:支持REST风格远程调用(HTTP + JSON/XML); 支持基于Kryo和FST的Java高效序列化实现; 支持基于嵌入式Tomcat的HTTP remoting体系。
dubbo添加REST调用,其最主要到目的也是面向服务的提供端,即开发REST服务来提供给非dubbo的(异构)消费端。
A.服务端pom配置:
要引用2.8.4版本dubbo框架并且排除spring的依赖

 <dependencies>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>dubbo</artifactId>
            <version>2.8.4</version>
             <exclusions>
                <exclusion>
                <!--    排除传递spring依赖 -->
                    <artifactId>spring</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
            </exclusions>
        </dependency>
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.15.0-GA</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty</artifactId>
            <version>3.7.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.2.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.1.39</version>
        </dependency>
        <dependency>
            <groupId>org.apache.bsf</groupId>
            <artifactId>bsf-api</artifactId>
            <version>3.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-simple</artifactId>
            <version>2.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>2.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.thrift</groupId>
            <artifactId>libthrift</artifactId>
            <version>0.8.0</version>
        </dependency>
        <dependency>
            <groupId>com.caucho</groupId>
            <artifactId>hessian</artifactId>
            <version>4.0.7</version>
        </dependency>
         <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency> 
        <!-- 要将 org.mortbay.jettyJAR包中的servlet-->
        <dependency>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>jetty</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.mortbay.jetty</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
            </exclusions>
            <version>6.1.26</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
             <version>1.2.16</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.2</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
           <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>javax.validation</groupId>
            <artifactId>validation-api</artifactId>
            <version>1.0.0.GA</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>4.2.0.Final</version>
        </dependency>
        <dependency>
            <groupId>javax.cache</groupId>
            <artifactId>cache-api</artifactId>
            <version>0.4</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxrs</artifactId>
            <version>3.0.7.Final</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-client</artifactId>
            <version>3.0.7.Final</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-netty</artifactId>
            <version>3.0.7.Final</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jdk-http</artifactId>
            <version>3.0.7.Final</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jackson-provider</artifactId>
            <version>3.0.7.Final</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.resteasy</groupId>
            <artifactId>resteasy-jaxb-provider</artifactId>
            <version>3.0.7.Final</version>
        </dependency>

        <!-- <dependency>   注意:此JAR包中也包含servlet类,如果使用要注意排除其中的servlet
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>8.0.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-logging-juli</artifactId>
            <version>8.0.11</version>
        </dependency> -->
        <!-- KRYO 高性能序列化库 -->
        <dependency>
            <groupId>com.esotericsoftware.kryo</groupId>
            <artifactId>kryo</artifactId>
            <version>2.24.0</version>
        </dependency>
        <dependency>
            <groupId>de.javakaffee</groupId>
            <artifactId>kryo-serializers</artifactId>
            <version>0.26</version>
        </dependency>
        <dependency>
            <groupId>de.ruedigermoeller</groupId>
            <artifactId>fst</artifactId>
             <version>1.55</version>
      </dependency>

        <dependency>
            <groupId>com.deppon.gis</groupId>
            <artifactId>restapi</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <!-- RESTFUL JAR包 -->
        <dependency>  
                <groupId>javax.ws.rs</groupId>  
                <artifactId>javax.ws.rs-api</artifactId>  
                <version>2.0</version>  
            </dependency>
         <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>
   </dependencies>

B.服务端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_2_5.xsd"
    id="WebApp_ID" version="2.5">
<!-- dubbox 远程调用的配置 -->
<!-- 如果你是用spring的ContextLoaderListener来加载spring,则必须保证BootstrapListener配置在ContextLoaderListener之前,否则dubbo初始化会出错。 -->
   <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:dubbo/dubbo-*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>com.alibaba.dubbo.remoting.http.servlet.BootstrapListener</listener-class>
    </listener>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
</web-app>

C.服务端spring核心配置以及代码实现


<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" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
    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://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!-- 开放dubbo协议,serialization表示序列化的方案  optimizer表示执行序列化的类-->
    <dubbo:protocol name="dubbo" serialization="kryo" optimizer="com.alibaba.dubbo.demo.SerializationOptimizerImpl"/>
    <dubbo:protocol name="dubbo" serialization="fst" optimizer="com.alibaba.dubbo.demo.SerializationOptimizerImpl"/>
    <dubbo:protocol name="dubbo" serialization="nativejava"/>
    <dubbo:protocol name="dubbo" serialization="hessian2"/>
    <dubbo:protocol name="dubbo" serialization="fastjson"/>
    <dubbo:protocol name="dubbo" serialization="dubbo"/>
    <!-- name:使用的协议  port:端口号   
     contextpath:所有rest服务对应的基础路径  
     server:如果为servlet,那么在web.xml中DispatcherServlet访问路径必须是 contextpath配置的访问路径
     extension:配置拦截器,多个拦截器类似于逗号分开
    -->
     <!-- 提供方应用信息,用于计算依赖关系   owner:该应用的负责人 -->
    <dubbo:application name="demo-provider" />
     <!-- 注册中心地址 -->
    <dubbo:registry address="zookeeper://10.230.13.74:2181"/>
    <!-- 开启dubbo注解扫描 -->
    <dubbo:annotation package="com.deppon.gis.service" />  
    <!--  name:使用的协议  
        port:端口号   
     contextpath:所有rest服务对应的基础路径  
     server:如果为servlet,那么在web.xml中DispatcherServlet访问路径必须是 contextpath配置的访问路径 
     extension:配置拦截器的实现类-->
     <!-- contextpath="services"  --><!-- server="servlet"  -->
    <dubbo:protocol name="rest"  port="9090"  contextpath="services" server="servlet" />
    <!-- extension="com.deppon.gis.filter.DubboxProviderFilter,
      com.deppon.gis.filter.DubboProvideCustomException,com.deppon.gis.filter.DubboConsumerFilter"extension 此属性值为自定义的dubbo拦截类需要实现ClientResponseFilter或者ContainerResponseFilter接口,可自行百度,此处不做演示 -->
   <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="com.deppon.gis.service.DubboProviderService" ref="dubboProviderServiceImpl"
      protocol="rest" validation="true"  timeout="2000" connections="100" />

    <bean id="dubboProviderServiceImpl" class="com.deppon.gis.provider.impl.DubboProviderServiceImpl" />

</beans>


import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

import com.alibaba.dubbo.rpc.protocol.rest.support.ContentType;
//接口上面不添加注解,保持接口的广泛适用性,使用dubbo客户端调用必须添加在接口上面
@Path("/restdemo")  //访问路径
public interface DubboProviderService {
      @GET  //请求方式
      @Path("/{param}")  //访问路径,并且请求参数加如正则校验必须是数组
      @Produces({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8})  
      public String queryService(@PathParam("param") int name);
}

import com.deppon.gis.service.DubboProviderService;

public class DubboProviderServiceImpl implements DubboProviderService{

       //指定输出JSON格式的数据。框架会自动将对象序列化为JSON数据。application/json; charset=UTF-8,text/xml;charset=UTF-8
        public String queryService(int name) {
                return "客户端使用restful风格调用服务端不使用servlet,返回字符串 name="+name ;
        }
}

A.非dubbo客户端调用duboo-rest服务端
这里写图片描述
B.dubbo客户端调用dubbo服务端
服务端配置文件:
这里写图片描述
客户端配置文件:
这里写图片描述
运行结果:
这里写图片描述
C.dubbo客户端调用非dubbo服务端
服务端配置文件:
这里写图片描述
这里写图片描述
接口:
这里写图片描述
客户端配置文件:
这里写图片描述
实现:
这里写图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章