一、dubbo介绍
-
dubbo是什么?
本质:一个Jar包,一个分布式框架,,一个远程服务调用的分布式框架。 既然是新手教学,肯定很多同学不明白什么是分布式和远程服务调用,为什么要分布式,为什么要 远程调用。
-
Dubbo的好处?
- 透明化的远程方法调用,就像调用本地方法一样调用远程方法,只需简单配置,没有任何API侵 入。
- 软负载均衡及容错机制,可在内网替代F5等硬件负载均衡器,降低成本,减少单点。
- 服务自动注册与发现,不再需要写死服务提供方地址,注册中心基于接口名查询服务提供者的IP 地址,并且能够平滑添加或删除服务提供者。
- Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载 Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。
-
dubbo架构
0. 服务容器负责启动,加载,运行服务提供者。 1. 服务提供者(生产者)在启动时,向注册中心注册自己提供的服务。 2. 服务消费者在启动时,向注册中心订阅自己所需的服务。 3. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据 给消费者。 4. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。 5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
二、zookeeper介绍
- zookeeper介绍
-
zookeeper实际上是yahoo开发的,用于分布式中一致性处理的框架。
-
背景介绍:最初其作为研发Hadoop时的副产品。由于分布式系统中一致性 处理较为困难,其他的分布式系统没有必要 费劲重复造轮子,故随后的分布式 系统中大量应用了zookeeper。故随后的大部分分布式系统中大量应用了 zookeeper,以至于zookeeper成为了各种分布式系统的基础组件,其地位之 重要,可想而知。(类比下之前学习过的netty,netty是对 socket 网络编程的优秀包装,是一个通讯组件框架。不了解netty的可以再花五分钟学习下,这么说吧,Netty很简单,其实就是个Jar包,是作为通讯组件用的)
-
具体应用场景:著名的hadoop、kafka、dubbo 都是基于zookeeper而构 建。
-
好处:保证在分布式环境下数据的最终一致性,这个就是zookeeper能解决 的问题。
-
上面提到了很多次一致性,那么究竟什么是一致性,给大家补充下这个概 念:
所谓的一致性,实际上就是围绕着“看见”来的。谁能看见?能否看见?什么时 候看见?
举个例子:
淘宝后台卖家,在后台上架一件大促的商品,通过服务器A 提交到主数据库,假设刚提交后立马就有用户去通过应用服务器B去从数据库查 询该商品,就会出现一个现象,卖家已经更新成功了,然而买家却看不到;
而经 过一段时间后,主数据库的数据同步到了从数据库,买家才能查到。(真技术 文)假设卖家更新成功之后买家立马就能看到卖家的更新,则称为强一致性; 如果卖家更新成功后买家不能看到卖家更新的内容,则称为弱一致性; 而卖家更新成功后,买家经过一段时间最终能看到卖家的更新,则称为最终一致性。
-
三、项目开发及配置文件
-
dubbo项目目录结构(maven)
注: spa_parent、spa_common、spa_interface建立后,maven工程先测试安装下;
spa_common(无骨架):存放实体类,工具类等;
spa_interface(无骨架):存放接口等(如:service接口);
spa_provider(webapp骨架):存放dao层接口、mapper映射文件和service接口实现类等;
spa_web(webapp骨架):controller层代码、后台项目代码及页面代码等。
-
pom依赖
spa_common:jar包<packaging>jar</packaging>
spa_interface:jar包,依赖spa_common
<packaging>jar</packaging> <dependencies> <dependency> <groupId>com.sys</groupId> <artifactId>spa_common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
spa_provider:war包,依赖spa_interface
<packaging>war</packaging> <dependencies> <dependency> <groupId>com.sys</groupId> <artifactId>spa_interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <configuration> <!-- 指定端口 --> <port>8081</port> <!-- 请求路径 --> <path>/</path> </configuration> </plugin> </plugins> </build>
spa_web:war包,依赖spa_interface
<packaging>war</packaging> <dependencies> <dependency> <groupId>com.sys</groupId> <artifactId>spa_interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <configuration> <!-- 指定端口 --> <port>8082</port> <!-- 请求路径 --> <path>/</path> </configuration> </plugin> </plugins> </build>
-
resources资源配置文件
-
spa_provicer
spring-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:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" 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.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 指定应用名称 --> <dubbo:application name="spa_provider"/> <!--指定暴露服务的端口,如果不指定默认为20880--> <dubbo:protocol name="dubbo" port="20887"/> <!--指定服务注册中心地址--> <dubbo:registry address="zookeeper://127.0.0.1:2181"/> <!--批量扫描,发布服务--> <dubbo:annotation package="com.sys.service"/> </beans>
spring-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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd"> <!--数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="username" value="root" /> <property name="password" value="root" /> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/spa_dubbo?characterEncoding=UTF-8" /> </bean> <!--spring和mybatis整合的工厂bean--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:SqlMapConfig.xml" /> </bean> <!--批量扫描接口生成代理对象--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--指定接口所在的包--> <property name="basePackage" value="com.sys.dao" /> </bean> </beans>
spring-tx.xml
<property name="dataSource" ref="dataSource"/>
:ref="dataSource"
的dataSource书写时报错,不用管,加载时自动加载<?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:tx="http://www.springframework.org/schema/tx" 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.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"> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 开启事务控制的注解支持 注意:此处必须加入proxy-target-class="true", 需要进行事务控制,会由Spring框架产生代理对象, Dubbo需要将Service发布为服务,要求必须使用cglib创建代理对象。 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> </beans>
SqlMapConfig.xml
<?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> <plugins> <!-- com.github.pagehelper 为 PageHelper 类所在包名 --> <plugin interceptor="com.github.pagehelper.PageHelper"> <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL 六种数据库--> <property name="dialect" value="mysql"/> </plugin> </plugins> </configuration>
-
spa_web
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:context="http://www.springframework.org/schema/context" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" 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.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <mvc:annotation-driven/> <dubbo:annotation package="com.sys"/> <context:component-scan base-package="com.sys"/> <mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <property name="supportedMediaTypes" value="application/json"/> <property name="features"> <list> <value>WriteMapNullValue</value> <value>WriteDateUseDateFormat</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <!-- 指定应用名称 --> <dubbo:application name="spa-web" /> <!--指定服务注册中心地址--> <dubbo:registry address="zookeeper://127.0.0.1:2181"/> <!-- 超时全局设置 10分钟 check=false 不检查服务提供方,开发阶段建议设置为false check=true 启动时检查服务提供方,如果服务提供方没有启动则报错 --> <dubbo:consumer timeout="600000" check="false"/> <!--文件上传组件--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="104857600"/> <property name="maxInMemorySize" value="4096"/> <property name="defaultEncoding" value="UTF-8"/> </bean> <!-- <import resource="spring-redis.xml"></import> <import resource="spring-security.xml"></import>--> </beans>
-
-
注解使用
- service接口实现类使用dubbo的service注解
@Service(interfaceClass = SpaItemService.class)
- controller层调用接口,使用注解
@Reference
,如:@Reference private SpaItemService spaItemService;
- service接口实现类使用dubbo的service注解
-
web.xml配置
- spa_provider
web.xml,加载spring容器<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!-- 加载spring容器 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
- spa_web
web.xml<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!-- 解决post乱码 --> <filter> <filter-name>CharacterEncodingFilter</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> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载 --> <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>*.do</url-pattern> </servlet-mapping> </web-app>
- spa_provider
-
启动事项
两个web项目都要启动(spa_provider和spa_web),还要启动zookeeper服务;
当spa_common、spa_interface项目有改动时,要重新 install 安装