Dubbo基礎 (一):簡介及搭建

Dubbo是:

  • 一個分佈式、高性能、透明化的RPC服務框架。
  • 提供服務的自動註冊、自動發現等高效服務自理方案。
  • 主要功能包括:高性能NIO通訊及多協議集成,服務動態尋址與路由,軟負載均衡與容錯,依賴分析與降級等。

Dubbo結構與功能:

  1. container負責啓動、加載、運行provider
  2. provider啓動時,向registry註冊自己的服務
  3. cousumer啓動時,向registry訂閱自己的服務
  4. registry提供provider列表給consumer,實時推送變動情況
  5. consumer根據provider列表,按負載算法選一臺provider調用
  6. monitor統計rpc的調用頻次

項目中部署的dubbo:

  1. 一臺應用服務(application)內,既有對外提供服務(provider),也有依賴外部服務(consumer)。

  2. provider涉及:registry/protocol/service/method/provider

  3. consumer涉及:registry/reference/method/consumer

  4. 每臺服務接口的信息,都會反映到monitor。以application的名稱標識屬於哪個應用。

簡單搭建一個分佈式項目,服務用dubbo來管理:

環境依賴:zookeeper,jdk1.8,tomcat7,dubbo-admin(控制檯)

dubbo-admin安裝:

  1.     下載地址:https://github.com/apache/incubator-dubbo/archive/dubbo-2.6.0.zip
  2.      解壓進入dubbo-admin目錄下,打開命令窗口,輸入命令 mvn clean package
  3.      將war包解壓,找到dubbo配置文件dubbo.properties修改zk連接地址
  4.      將這個文件夾放到tomcat的webapps目錄下,啓動tomcat
  5.      輸入localhost:8080/文件名,用戶名/密碼    root/root

一、新建一個簡單的mvc項目 storePortal

pom文件除了引入mvc必備的依賴,還需要引入dubbo相關依賴

       <dependency>
        	<groupId>com.101tec</groupId>
        	<artifactId>zkclient</artifactId>
        	<version>0.3</version>
        </dependency>
        
        <dependency>
        	<groupId>org.apache.zookeeper</groupId>
        	<artifactId>zookeeper</artifactId>
        	<version>3.4.5</version>
        </dependency>
		    
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
			<version>2.6.0</version>
			<scope>compile</scope>
			<exclusions>
				<exclusion>
					<artifactId>spring</artifactId>
					<groupId>org.springframework</groupId>
				</exclusion>
			</exclusions>
         </dependency>

這個模塊需要被外界訪問,添加一個tomcat插件,或者打包後放到tomcat中

<build>
	   <plugins>
			<!-- 配置Tomcat插件 -->
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<configuration>
					<port>8080</port>
					<path>/</path>
				</configuration>
			</plugin>
		</plugins>
   </build>

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" version="2.5">
  <display-name>storePortal</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <!-- Spring MVC servlet -->
    <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</param-value>  
        </init-param>  
        <load-on-startup>1</load-on-startup>  
        
    </servlet>  
    <servlet-mapping>  
        <servlet-name>SpringMVC</servlet-name>  
        <!-- 此處可以可以配置成*.do,對應struts的後綴習慣 -->  
        <url-pattern>/</url-pattern>  
    </servlet-mapping>  
    <welcome-file-list>  
        <welcome-file>/index.jsp</welcome-file>  
    </welcome-file-list>  
</web-app>

dubbo配置方式有XML、peoperties、註解和api方式:

xml方式:

服務提供方:xml配置是將服務類交給spring的ioc容器,在由dubbo將服務開放成rpc服務,對外提供服務,所以在服務類上不需要加@Service註解

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

    <context:component-scan base-package="com.enjoy.dao"/>

    <!-- 提供方應用信息,用於計算依賴關係 -->
    <dubbo:application name="storeServer"/>

    <!-- 使用zookeeper註冊中心暴露服務地址 -->
    <dubbo:registry address="zookeeper://192.168.244.2:2181"/>

    <!-- 用dubbo協議在20880端口暴露服務 -->
    <dubbo:protocol name="dubbo" port="20880"/>
    <dubbo:protocol name="rmi" port="21880"/>

    <!-- 
               聲明需要暴露的服務接口
        dubbo把ioc容器內的service開放成rpc服務 
     -->
    <dubbo:service interface="com.enjoy.service.OrderService" ref="orderService" >
        <!-- <dubbo:method name="getDetail" cache="lru" /> -->
    </dubbo:service>

    <dubbo:service interface="com.enjoy.service.UserService" ref="userService" />
    <dubbo:service interface="com.enjoy.service.VipUserService" ref="vipUserService" />

     <!--
                 和本地bean一樣實現服務 
                 把服務交給ioc容器管理
     -->
    <bean id="orderService" class="com.enjoy.service.impl.OrderServiceImpl"/>
    <bean id="userService" class="com.enjoy.service.impl.UserServiceImpl"/>
    <bean id="vipUserService" class="com.enjoy.service.impl.VipUserServiceImpl"/>

服務消費方:xml方式是將引用的服務交給spring的ioc容器,如果從容器中取得這個服務,需要用@Autowired註解

<?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="enjoyStore"/>

    <!-- 使用zookeeper註冊中心暴露服務地址 -->
    <dubbo:registry address="zookeeper://192.168.244.2:2181"/>

    <!-- 生成遠程服務代理,可以和本地bean一樣使用demoService -->
    <dubbo:reference id="orderService" interface="com.enjoy.service.OrderService" >
    </dubbo:reference>

    <dubbo:reference id="userService" interface="com.enjoy.service.UserService"  />
    <dubbo:reference id="vipUserService" interface="com.enjoy.service.VipUserService"  />


</beans>
@Controller
public class IndexController implements ApplicationContextAware{
	 private ApplicationContext context;

	   
	    @Autowired
	    private UserService userService;

	   
	    @Autowired
	    private OrderService orderService;
}

這樣就可以使用這個服務。

properties方式:是對xml方式的補充,如果xml配置裏沒有定義的配置信息,dubbo會從dubbo.properties這個文件中讀取,如果xml中定義了相關信息,則peoperties的相關配置不會生效,properties文件的級別最低,一般將連接信息配置到properties文件,並且這個文件放在Resources文件夾下,起名dubbo.properties,dubbo會自動加載這個文件

# 應用名
dubbo.application.name=enjoyStore_properties
# 註冊中心地址
dubbo.registry.address=zookeeper://192.168.244.2:2181
# 調用協議地址
dubbo.protocol.name=dubbo
dubbo.protocol.port=28080

註解方式配置dubbo

服務提供方:註解方式是在xml里加一個掃描包,掃描指定包下的類,如果發現類上加了@Service(這個註解是dubbo的註解)這個註解,那麼就會將這個類交給spring的ioc容器管理,並將這個類開放成rpc服務,對外提供服務

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

    <context:component-scan base-package="com.enjoy.dao"/>

    <!-- 提供方應用信息,用於計算依賴關係 -->
    <dubbo:application name="storeServer_annotation"/>

    <!-- 使用zookeeper註冊中心暴露服務地址 -->
    <dubbo:registry address="zookeeper://192.168.244.2:2181"/>

    <!-- 用dubbo協議在20880端口暴露服務 -->
    <dubbo:protocol name="rmi" port="20880"/>

    <dubbo:annotation package="com.enjoy.service" />

</beans>

服務消費方:註解方式是指定掃描包,掃描指定包下的類,發現哪個類的成員變量上加了@Reference註解(dubbo註解),就會將這個代理服務對象注入到這個類上,完成調用。這裏不能用spring的註解,必須用dubbo的註解才能完成引用

@Controller
public class IndexController implements ApplicationContextAware{
	 private ApplicationContext context;

	    @Reference
	    private UserService userService;

	    @Reference
	    private OrderService orderService;
}

API方式:這種方式開發時不會使用,但是這種方式結構看起來會清晰一些,方便學習使用

服務提供方:

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.ServiceConfig;
import com.enjoy.service.VipUserService;
import com.enjoy.service.impl.VipUserServiceImpl;

import java.io.IOException;

public class StoreProvider {
    public static void main(String[] args) throws IOException {
        initDubbo();
    }

    public static void initDubbo() throws IOException {
            // 當前應用配置
            ApplicationConfig application = new ApplicationConfig();
            application.setName("StoreServerApi");

            // 連接註冊中心配置
            RegistryConfig registry = new RegistryConfig();
            registry.setProtocol("zookeeper");
            registry.setAddress("192.168.244.2:2181");

            // 服務提供者協議配置
            ProtocolConfig protocol = new ProtocolConfig();
            protocol.setName("rmi");
            protocol.setPort(21880);
            protocol.setThreads(100);

            // 注意:ServiceConfig爲重對象,內部封裝了與註冊中心的連接,以及開啓服務端口
            // 服務提供者暴露服務配置
            // 此實例很重,封裝了與註冊中心的連接,請自行緩存,否則可能造成內存和連接泄漏
            ServiceConfig<VipUserService> service = new ServiceConfig<>();

            service.setApplication(application);
            service.setRegistry(registry); // 多個註冊中心可以用setRegistries()
            service.setProtocol(protocol); // 多個協議可以用setProtocols()
            service.setInterface(VipUserService.class);
            service.setRef(new VipUserServiceImpl());

            // 暴露及註冊服務
            service.export();
            System.out.println("dubbo服務開啓。。。。。。。。");
            System.in.read();

    }
}

服務消費方:

import com.alibaba.dubbo.config.*;
import com.enjoy.service.VipUserService;
import java.io.IOException;

public class StoreConsumer {
    public static void main(String[] args) throws IOException {
        // 當前應用配置
        ApplicationConfig application = new ApplicationConfig();
        application.setName("StoreServerClientApi");

        // 連接註冊中心配置
        RegistryConfig registry = new RegistryConfig();
        registry.setProtocol("zookeeper");
        registry.setAddress("192.168.244.2:2181");

        // 服務提供者協議配置
        ProtocolConfig protocol = new ProtocolConfig();
        protocol.setName("dubbo");
        protocol.setPort(20882);
        protocol.setThreads(100);

        // 注意:ReferenceConfig爲重對象,內部封裝了與註冊中心的連接,以及與服務提供方的連接
        // 引用遠程服務
        ReferenceConfig<VipUserService> reference = new ReferenceConfig<>(); // 此實例很重,封裝了與註冊中心的連接以及與提供者的連接,請自行緩存,否則可能造成內存和連接泄漏
        reference.setApplication(application);
        reference.setRegistry(registry); // 多個註冊中心可以用setRegistries()
        reference.setInterface(VipUserService.class);

        // 和本地bean一樣使用xxxService
        VipUserService vipUserService = reference.get(); // 注意:此代理對象內部封裝了所有通訊細節,對象較重,請緩存複用
        String ret = vipUserService.getVipDetail("123");
        reference.destroy();
        System.out.println(ret);
        System.in.read();
    }
}

 

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