java后端学习 SSM整合dubbo+zookeeper

最近刚好有点时间,特意来整合一下项目,以后会陆续把前端框架和一些组件也给整合进去,今天就先来整合一下SSM+mysql+dubbo+zookeeper来做一个用户列表功能。关于理论性的知识,大家可以自行查阅下资料,这里重点讲解一下怎么搭建这一套开发环境。

背景

随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

  • 单一应用架构
    • 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。
    • 此时,用于简化增删改查工作量的 数据访问框架(ORM) 是关键。
    • 早期的JSP,ASP,PHP都是把数据操作写在前端,功能相当简单。
  • 垂直应用架构
    • 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。
    • 此时,用于加速前端页面开发的 Web框架(MVC) 是关键。现在很多非互联网公司仍然采用这种架构设计。
  • 分布式服务架构
    • 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
    • 此时,用于提高业务复用及整合的 分布式服务框架(RPC) 是关键。
  • 流动计算架构
    • 当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。
    • 此时,用于提高机器利用率的 资源调度和治理中心(SOA) 是关键。

开发工具:

这里贴出自己的开发工具和版本号,因为有的时候可能会因为版本号而造成很多不必要的冲突。

zookeeper-3.4.6+windows系统+mysql 5.6+jdk7+eclipse+tomcat7+dubbo 2.5.3

zookeeper:

下载zookeeper注册中心,下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/ 下载后解压即可。


然后进入conf里面,改一下我们的配置,打开zoo.cfg,有得可能不叫这个名字,把zoo_sample.cfg改成zoo.cfg


    
    
  1. clientPort=2181
  2. #server.1=127.0.0.1:3881:4881
  3. #server.2=127.0.0.1:3882:4882
  4. #server.3=127.0.0.1:3883:4883
  5. dataDir=../data
  6. dataLogDir=../log
  7. # The number of milliseconds of each tick
  8. tickTime=10000
  9. # The number of ticks that the initial
  10. # synchronization phase can take
  11. initLimit=10
  12. # The number of ticks that can pass between
  13. # sending a request and getting an acknowledgement
  14. syncLimit=5
  15. # the directory where the snapshot is stored.
  16. # do not use /tmp for storage, /tmp here is just
  17. # example sakes.
  18. #dataDir=../data
  19. #dataLogDir=../dataLog
  20. # the port at which the clients will connect
  21. #clientPort=2181
  22. # the maximum number of client connections.
  23. # increase this if you need to handle more clients
  24. #maxClientCnxns=60
  25. #
  26. # Be sure to read the maintenance section of the
  27. # administrator guide before turning on autopurge.
  28. #
  29. # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
  30. #
  31. # The number of snapshots to retain in dataDir
  32. #autopurge.snapRetainCount=3
  33. # Purge task interval in hours
  34. # Set to "0" to disable auto purge feature
  35. #autopurge.purgeInterval=1
tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
当这些配置项配置好后,你现在就可以启动 Zookeeper 了,启动后要检查 Zookeeper 是否已经在服务,可以通过 netstat – ano 命令查看是否有你配置的 clientPort 端口号在监听服务。

  • server.A=B:C:D:其中 A 是一个数字,表示这个是第几号服务器;B 是这个服务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。


最后到bin目录下面启动,客户端和服务端。


Dubbo:

需要下载:dubbo-admin-2.5.3的war

然后Tomcat启动一下。这里有两种启动方式,一种是找到自己的tomcat安装目录,替换掉tomcat/webapps下自带的ROOT文件夹内容(即替换tomcat的启动主页),将下载的war包解压到webapps/ROOT中,直接替换即可。

我用的是下面这种,比较简单点。打开eclipse里面的tomcat管理页面。


然后选择第二个,找到自己刚刚下载的war包,部署并且启动一下。

这个时候在浏览器输入自己的ip和端口,我的是localhost:8080


看到这个管理页面就代表成功了。可以来检测我们的消费者和生产者了。

SSM整合:

这里先编写我们的服务端,我把提供服务的统称为服务端,所以这里先创建一个服务端。

所以这里新建一个项目叫做user-service

Maven引入需要的JAR包


     
     
  1. <?xml version="1.0"?>
  2. <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance">
  4. <modelVersion>4.0.0 </modelVersion>
  5. <parent>
  6. <groupId>user </groupId>
  7. <artifactId>user </artifactId>
  8. <version>0.0.1-SNAPSHOT </version>
  9. </parent>
  10. <artifactId>user-service </artifactId>
  11. <packaging>jar </packaging>
  12. <!-- <name>user-service Maven Webapp</name>
  13. <url>http://maven.apache.org</url> -->
  14. <properties>
  15. <project.build.sourceEncoding>UTF-8 </project.build.sourceEncoding>
  16. <!-- 设置 Spring 的版本 -->
  17. <org.springframework.version>4.1.7.RELEASE </org.springframework.version>
  18. </properties>
  19. <dependencies>
  20. <dependency>
  21. <groupId>user-api </groupId>
  22. <artifactId>user-api </artifactId>
  23. <version>0.0.1-SNAPSHOT </version>
  24. </dependency>
  25. <dependency>
  26. <groupId>junit </groupId>
  27. <artifactId>junit </artifactId>
  28. <version>3.8.1 </version>
  29. <scope>test </scope>
  30. </dependency>
  31. <dependency>
  32. <groupId>com.alibaba </groupId>
  33. <artifactId>dubbo </artifactId>
  34. <version>2.5.3 </version>
  35. <exclusions>
  36. <exclusion>
  37. <artifactId>spring </artifactId>
  38. <groupId>org.springframework </groupId>
  39. </exclusion>
  40. </exclusions>
  41. </dependency>
  42. <dependency>
  43. <groupId>org.apache.zookeeper </groupId>
  44. <artifactId>zookeeper </artifactId>
  45. <version>3.4.6 </version>
  46. <exclusions>
  47. <exclusion>
  48. <artifactId>log4j </artifactId>
  49. <groupId>log4j </groupId>
  50. </exclusion>
  51. </exclusions>
  52. </dependency>
  53. <dependency>
  54. <groupId>org.slf4j </groupId>
  55. <artifactId>slf4j-api </artifactId>
  56. <version>1.7.12 </version>
  57. </dependency>
  58. <dependency>
  59. <groupId>ch.qos.logback </groupId>
  60. <artifactId>logback-core </artifactId>
  61. <version>1.1.1 </version>
  62. </dependency>
  63. <!-- 实现slf4j接口并整合 -->
  64. <dependency>
  65. <groupId>ch.qos.logback </groupId>
  66. <artifactId>logback-classic </artifactId>
  67. <version>1.1.1 </version>
  68. </dependency>
  69. <!--2:数据库相关依赖 -->
  70. <dependency>
  71. <groupId>mysql </groupId>
  72. <artifactId>mysql-connector-java </artifactId>
  73. <version>5.1.35 </version>
  74. <scope>runtime </scope>
  75. </dependency>
  76. <dependency>
  77. <groupId>c3p0 </groupId>
  78. <artifactId>c3p0 </artifactId>
  79. <version>0.9.1.2 </version>
  80. </dependency>
  81. <!-- DAO框架:MyBatis依赖 -->
  82. <dependency>
  83. <groupId>org.mybatis </groupId>
  84. <artifactId>mybatis </artifactId>
  85. <version>3.3.0 </version>
  86. </dependency>
  87. <!-- mybats自身实现的spring整合依赖 -->
  88. <dependency>
  89. <groupId>org.mybatis </groupId>
  90. <artifactId>mybatis-spring </artifactId>
  91. <version>1.2.3 </version>
  92. </dependency>
  93. <!-- 3:Servlet web相关依赖 -->
  94. <dependency>
  95. <groupId>taglibs </groupId>
  96. <artifactId>standard </artifactId>
  97. <version>1.1.2 </version>
  98. </dependency>
  99. <dependency>
  100. <groupId>jstl </groupId>
  101. <artifactId>jstl </artifactId>
  102. <version>1.2 </version>
  103. </dependency>
  104. <dependency>
  105. <groupId>com.fasterxml.jackson.core </groupId>
  106. <artifactId>jackson-databind </artifactId>
  107. <version>2.5.4 </version>
  108. </dependency>
  109. <dependency>
  110. <groupId>javax.servlet </groupId>
  111. <artifactId>javax.servlet-api </artifactId>
  112. <version>3.1.0 </version>
  113. </dependency>
  114. <!--4:spring依赖 -->
  115. <!--1)spring核心依赖 -->
  116. <dependency>
  117. <groupId>org.springframework </groupId>
  118. <artifactId>spring-core </artifactId>
  119. <version>${org.springframework.version} </version>
  120. </dependency>
  121. <dependency>
  122. <groupId>org.springframework </groupId>
  123. <artifactId>spring-beans </artifactId>
  124. <version>${org.springframework.version} </version>
  125. </dependency>
  126. <dependency>
  127. <groupId>org.springframework </groupId>
  128. <artifactId>spring-context </artifactId>
  129. <version>${org.springframework.version} </version>
  130. </dependency>
  131. <!--2)spring dao层依赖 -->
  132. <dependency>
  133. <groupId>org.springframework </groupId>
  134. <artifactId>spring-jdbc </artifactId>
  135. <version>${org.springframework.version} </version>
  136. </dependency>
  137. <dependency>
  138. <groupId>org.springframework </groupId>
  139. <artifactId>spring-tx </artifactId>
  140. <version>${org.springframework.version} </version>
  141. </dependency>
  142. <!--3)spring web相关依赖 -->
  143. <dependency>
  144. <groupId>org.springframework </groupId>
  145. <artifactId>spring-web </artifactId>
  146. <version>${org.springframework.version} </version>
  147. </dependency>
  148. <dependency>
  149. <groupId>org.springframework </groupId>
  150. <artifactId>spring-webmvc </artifactId>
  151. <version>${org.springframework.version} </version>
  152. </dependency>
  153. <!-- 4)spring test相关依赖 -->
  154. <dependency>
  155. <groupId>org.springframework </groupId>
  156. <artifactId>spring-test </artifactId>
  157. <version>${org.springframework.version} </version>
  158. </dependency>
  159. <!-- redis客户端:Jedis -->
  160. <dependency>
  161. <groupId>redis.clients </groupId>
  162. <artifactId>jedis </artifactId>
  163. <version>2.7.3 </version>
  164. </dependency>
  165. <!-- protostuff序列化依赖 -->
  166. <dependency>
  167. <groupId>com.dyuproject.protostuff </groupId>
  168. <artifactId>protostuff-core </artifactId>
  169. <version>1.0.8 </version>
  170. </dependency>
  171. <dependency>
  172. <groupId>com.dyuproject.protostuff </groupId>
  173. <artifactId>protostuff-runtime </artifactId>
  174. <version>1.0.8 </version>
  175. </dependency>
  176. <dependency>
  177. <groupId>commons-collections </groupId>
  178. <artifactId>commons-collections </artifactId>
  179. <version>3.2 </version>
  180. </dependency>
  181. <dependency>
  182. <groupId>com.github.sgroschupf </groupId>
  183. <artifactId>zkclient </artifactId>
  184. <version>0.1 </version>
  185. </dependency>
  186. </dependencies>
  187. <!-- <build>
  188. <finalName>user-service</finalName>
  189. </build> -->
  190. </project>

Web.xml

这里使用contextConfigLocation来加载我们spring的配置文件。

     
     
  1. <servlet>
  2. <servlet-name>user-service </servlet-name>
  3. <servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class>
  4. <!-- 配置springMVC需要加载的配置文件 spring-dao.xml,spring-service.xml,spring-web.xml
  5. Mybatis -> spring -> springMVC -->
  6. <init-param>
  7. <param-name>contextConfigLocation </param-name>
  8. <param-value>classpath:spring/spring-*.xml </param-value>
  9. </init-param>
  10. </servlet>
  11. <servlet-mapping>
  12. <servlet-name>user-service </servlet-name>
  13. <!-- 默认匹配所有的请求 -->
  14. <url-pattern>/ </url-pattern>
  15. </servlet-mapping>

配置视图解析器:


     
     
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc= "http://www.springframework.org/schema/mvc"
  4. xmlns:context= "http://www.springframework.org/schema/context"
  5. xmlns:dubbo= "http://code.alibabatech.com/schema/dubbo"
  6. xsi:schemaLocation= "http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/mvc
  9. http://www.springframework.org/schema/mvc/spring-mvc.xsd
  10. http://www.springframework.org/schema/context
  11. http://www.springframework.org/schema/context/spring-context.xsd
  12. http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
  13. <!-- 配置SpringMVC -->
  14. <!-- 1:开启SpringMVC注解模式 -->
  15. <!-- 简化配置:
  16. (1)自动注册DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter
  17. (2)提供一系列:数据绑定,数字和日期的format @NumberFormat,@DataTimeFormat,
  18. xml,json默认读写支持.
  19. -->
  20. <mvc:annotation-driven/>
  21. <!--
  22. 2:静态资源默认servlet配置
  23. 1:加入对静态资源的处理:js,gif,png
  24. 2:允许使用"/"做整体映射
  25. -->
  26. <mvc:default-servlet-handler/>
  27. <!--3:配置jsp 显示ViewResolver -->
  28. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  29. <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
  30. <property name="prefix" value="/WEB-INF/jsp/"/>
  31. <property name="suffix" value=".jsp"/>
  32. </bean>
  33. <!--4:扫描web相关的bean -->
  34. <context:component-scan base-package="com.dubbo.controller"/>
  35. </beans>

建立JDBC属性文件

jdbc.properties(文件编码修改为utf-8)


     
     
  1. jdbc.driver=com.mysql.jdbc.Driver
  2. jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
  3. jdbc.username=root
  4. jdbc.password=root

Spring整合mybatis DAO层


     
     
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context= "http://www.springframework.org/schema/context"
  5. xsi:schemaLocation= "http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context.xsd">
  9. <!-- 配置整合mybatis过程 -->
  10. <!-- 1:配置数据库相关参数properties的属性:${url} -->
  11. <context:property-placeholder location="classpath:jdbc.properties"/>
  12. <!-- 2:数据库连接池 -->
  13. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  14. <!-- 配置连接池属性 -->
  15. <property name="driverClass" value="${jdbc.driver}"/>
  16. <property name="jdbcUrl" value="${jdbc.url}"/>
  17. <property name="user" value="${jdbc.username}"/>
  18. <property name="password" value="${jdbc.password}"/>
  19. <!-- c3p0连接池的私有属性 -->
  20. <property name="maxPoolSize" value="30"/>
  21. <property name="minPoolSize" value="10"/>
  22. <!-- 关闭连接后不自动commit -->
  23. <property name="autoCommitOnClose" value="false"/>
  24. <!-- 获取连接超时时间 -->
  25. <property name="checkoutTimeout" value="1000"/>
  26. <!-- 当获取连接失败重试次数 -->
  27. <property name="acquireRetryAttempts" value="2"/>
  28. </bean>
  29. <!-- 约定大于配置 -->
  30. <!-- 3:配置SqlSessionFactory对象 -->
  31. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  32. <!-- 注入数据库连接池 -->
  33. <property name="dataSource" ref="dataSource"/>
  34. <!-- 配置MyBatis全局配置文件:mybatis-config.xml -->
  35. <property name="configLocation" value="classpath:mybatis-config.xml"/>
  36. <!-- 扫描entity包 使用别名 -->
  37. <property name="typeAliasesPackage" value="com.dubbo.entity"/>
  38. <!-- 扫描sql配置文件:mapper需要的xml文件 -->
  39. <property name="mapperLocations" value="classpath:mapper/*.xml"/>
  40. </bean>
  41. <!-- 4:配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中-->
  42. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  43. <!-- 注入sqlSessionFactory -->
  44. <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
  45. <!-- 给出需要扫描Dao接口包 -->
  46. <property name="basePackage" value="com.dubbo.dao"/>
  47. </bean>
  48. <!-- RedisDao -->
  49. <bean id="redisDao" class="com.dubbo.dao.cache.RedisDao">
  50. <constructor-arg index="0" value="localhost"/>
  51. <constructor-arg index="1" value="6379"/>
  52. </bean>
  53. </beans>
redisDao以后会用到,现在先不管。

spring整合service层,开启事务


     
     
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context= "http://www.springframework.org/schema/context"
  5. xmlns:tx= "http://www.springframework.org/schema/tx"
  6. xsi:schemaLocation= "http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/context
  9. http://www.springframework.org/schema/context/spring-context.xsd
  10. http://www.springframework.org/schema/tx
  11. http://www.springframework.org/schema/tx/spring-tx.xsd">
  12. <!-- 扫描service包下所有使用注解的类型 -->
  13. <context:component-scan base-package="com.dubbo.service"/>
  14. <!-- 配置事务管理器 -->
  15. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  16. <!-- 注入数据库连接池 -->
  17. <property name="dataSource" ref="dataSource"/>
  18. </bean>
  19. <!-- 配置基于注解的声明式事务
  20. 默认使用注解来管理事务行为
  21. -->
  22. <tx:annotation-driven transaction-manager="transactionManager"/>
  23. <!-- 具体的实现bean -->
  24. </beans>

mybatis配置文件


     
     
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <!-- 配置全局属性 -->
  7. <settings>
  8. <!-- 使用jdbc的getGeneratedKeys 获取数据库自增主键值 -->
  9. <setting name="useGeneratedKeys" value="true"/>
  10. <!-- 使用列别名替换列名 默认:true
  11. select name as title from table
  12. -->
  13. <setting name="useColumnLabel" value="true"/>
  14. <!-- 开启驼峰命名转换:Table(create_time) -> Entity(createTime) -->
  15. <setting name="mapUnderscoreToCamelCase" value="true"/>
  16. </settings>
  17. </configuration>
基本上配置就这些,log4我感觉用处不大,懒得配置了。下面还有有一些mybatis的xml配置,这个后面再讲。

mysql:

创建我们的sql


     
     
  1. CREATE TABLE `user` (
  2. `userId` BIGINT ( 20),
  3. `userName` VARCHAR ( 108),
  4. `account` VARCHAR ( 108),
  5. `password` VARCHAR ( 108),
  6. `phone` VARCHAR ( 66),
  7. `address` VARCHAR ( 108)
  8. ); DEFAULT CHARSET=utf8;

简单创建几个字段,随便加几条数据就好。

创建实体类:

在创建实体类之前我先把包结构给建立好了;


在我们的entity里面创建一下User的实体类。


     
     
  1. public class User implements Serializable{
  2. private String userId;
  3. private String userName;
  4. private String account;
  5. private String phone;
  6. private String password;
  7. private String address;
  8. public String getUserId() {
  9. return userId;
  10. }
  11. public void setUserId(String userId) {
  12. this.userId = userId;
  13. }
  14. public String getUserName() {
  15. return userName;
  16. }
  17. public void setUserName(String userName) {
  18. this.userName = userName;
  19. }
  20. public String getAccount() {
  21. return account;
  22. }
  23. public void setAccount(String account) {
  24. this.account = account;
  25. }
  26. public String getPhone() {
  27. return phone;
  28. }
  29. public void setPhone(String phone) {
  30. this.phone = phone;
  31. }
  32. public String getAddress() {
  33. return address;
  34. }
  35. public void setAddress(String address) {
  36. this.address = address;
  37. }
  38. public String getPassword() {
  39. return password;
  40. }
  41. public void setPassword(String password) {
  42. this.password = password;
  43. }
  44. }

编写dao和service


     
     
  1. public interface UserDao {
  2. public List<User> getListUser();
  3. }


     
     
  1. public interface UserService {
  2. public List<User> getListUser();
  3. }


     
     
  1. @Service
  2. public class UserServiceImpl implements UserService {
  3. private final Logger logger = LoggerFactory.getLogger( this.getClass());
  4. //注入Service依赖
  5. @Autowired
  6. private UserDao userDao;
  7. /**
  8. * @return
  9. * @see com.dubbo.service.UserService#getListUser()
  10. *<pre>
  11. *<li>Author:</li>
  12. *<li>Date: 2016年9月23日</li>
  13. *</pre>
  14. */
  15. @Override
  16. public List<User> getListUser() {
  17. return userDao.getListUser();
  18. }
  19. }


     
     
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.dubbo.dao.UserDao">
  6. <!-- 目的:为DAO接口方法提供sql语句配置-->
  7. <select id="getListUser" resultType="User">
  8. SELECT*FROM USER
  9. </select>
  10. </mapper>

编写Controller


     
     
  1. @Autowired
  2. private UserService userService;
  3. @RequestMapping(value = "/list", method = RequestMethod.GET)
  4. public String list(Model model) {
  5. //获取列表页
  6. List<User> list = userService.getListUser();
  7. model.addAttribute( "list", list);
  8. //list.jsp + model = ModelAndView
  9. return "list"; // /WEB-INF/jsp/"list".jsp
  10. }

启动Tomcat测试:


整合Dubbo和zookeeper

在整合之前首先要明白Dubbo和zookeeper是干嘛用的。

SOA的框架也正是现在网站的系统架构演化史,也从侧面反映了我国网民数量的增加和对网站性能的提升。

大型网站系统特点

  (1)高并发、大流量:PV量巨大

  (2)高可用:7*24小时不间断服务

  (3)海量数据:文件数目分分钟xxTB

  (4)用户分布广泛,网络情况复杂:网络运营商

  (5)安全环境恶劣:黑客的攻击

  (6)需求快速变更,发布频繁:快速适应市场,满足用户需求

  (7)渐进式发展:慢慢地运营出大型网站


例子:

小明作为一个屌丝码农,有一天创建了一个网站,最开始只是小明一个人在运营,所有的程序都在一个Server里面跑,数据库访问和逻辑控制也都写在jsp文件里面。应用程序、数据库、文件等所有资源都集中在一台Server上。这就是典型的纯jsp网站。



后来他的好朋友小王来了,他觉得小明的网站做的不错,于是就提出了改造建议,小王可是受过培训的啊,什么MVC人家可是经常背,于是他们的网站就开始拆分MVC三层了。并且把文件服务器和数据库单独部署到一个Server上。

这个时候三台Server平天下,应用和数据服务分离。



再到后来,他们的网站越来越大了,普通的架构已经满足不了他们了,怎么办,必须得做集群,必须要有缓存,什么读写分离啊,redis啊和反向代理和CDN加速等等,慢慢的开始应用起来。

分布式服务:既然每一个应用系统都需要执行许多相通的业务操作,比如用户管理、商品管理等,那么可以将这些共用的业务提取出来,独立部署。


好了,其实dubbo简单来说就是用来管理我们的服务的,以前我们都是自己调自己的服务,如果服务挂掉的话,那么整个系统就挂掉了,现在是我们把服务交给dubbo去统一管理,而zookeeper是管理我们的dubbo的。

创建user-api;user-api的作用很简单,作为一个API,把接口暴露出来供我们的客户端调用。


     
     
  1. public interface UserService {
  2. public List getListUser();
  3. }
修改服务端代码,这里要修改一下我们的user-service。把他作为一个服务层,只和数据库进行交互。

Web-xml


     
     
  1. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
  3. http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  4. version="3.1" metadata-complete="true">
  5. <!-- 修改servlet版本为3.1 -->
  6. <!-- 配置DispatcherServlet -->
  7. <listener>
  8. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  9. </listener>
  10. <context-param>
  11. <param-name>contextConfigLocation</param-name>
  12. <param-value>classpath:spring/spring-*.xml</param-value>
  13. </context-param>
  14. <servlet>
  15. <servlet-name>user-service</servlet-name>
  16. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  17. <!-- 配置springMVC需要加载的配置文件 spring-dao.xml,spring-service.xml,spring-web.xml
  18. Mybatis -> spring -> springMVC -->
  19. <init-param>
  20. <param-name>contextConfigLocation</param-name>
  21. <param-value>classpath:spring/spring-*.xml</param-value>
  22. </init-param>
  23. </servlet>
  24. <servlet-mapping>
  25. <servlet-name>user-service</servlet-name>
  26. <!-- 默认匹配所有的请求 -->
  27. <url-pattern>/</url-pattern>
  28. </servlet-mapping>
  29. </web-app>
这里如果不用<listener>加载的话dubbo服务注册不上去,具体原因还没有找到,还有这里加载了两遍配置文件才起作用,具体原因也还在探索中(迷茫。。)最后一个拦截器,可以不需要,因为我们不通过user-service访问页面。
去掉service接口,这里我们通过引入user-api里面的接口,并且也基础里面的接口,所以user-service里面的接口可以去掉。

创建dubbo配置文件 spring-dubbo.xml


     
     
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:p= "http://www.springframework.org/schema/p"
  4. xmlns:dubbo= "http://code.alibabatech.com/schema/dubbo"
  5. xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
  6. http://code.alibabatech.com/schema/dubbo
  7. http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
  8. <!-- 提供方应用信息,用于计算依赖关系 -->
  9. <dubbo:application name="test_provider" />
  10. <!-- 使用zookeeper注册中心暴露服务地址 -->
  11. <dubbo:registry address="zookeeper://172.16.1.37:2181" />
  12. <!-- 用dubbo协议在20880端口暴露服务 -->
  13. <dubbo:protocol name="dubbo" port="20880" />
  14. <!-- 声明需要暴露的服务接口 -->
  15. <dubbo:service interface="com.dubbo.service.UserService" ref="userService" />
  16. <!-- 具体的实现bean -->
  17. <bean id="userService" class="com.dubbo.service.impl.UserServiceImpl" />
  18. <!-- 声明需要暴露的服务接口 -->
  19. <dubbo:service interface="com.dubbo.service.TestService" ref="testService" />
  20. <!-- 具体的实现bean -->
  21. <bean id="testService" class="com.dubbo.service.impl.TestServiceImpl" />
  22. <!-- 声明需要暴露的服务接口 -->
  23. <dubbo:service interface="com.dubbo.service.SeckillService" ref="seckillService" />
  24. <!-- 具体的实现bean -->
  25. <bean id="seckillService" class="com.dubbo.service.impl.SeckillServiceImpl" />
  26. </beans>

最后启动Tomcat;

我们使用zk-Inspector,来监控一下zk的服务。



点击绿色的箭头,然后开启监控,我们可以看到

dubbo服务已经注册成功,然后我们再进入dubbo管理页面看看。


也创建了三个服务,证明我们的服务端已经开发完成。

客户端:

这个时候要创建我们的客户端了,客户端也采用SSM架构,其实根本不用Mybatis,因为数据交互都交给了我们的客户端,这里直接把服务端的架构复制过来;

     
     
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo= "http://code.alibabatech.com/schema/dubbo"
  4. xsi:schemaLocation= "http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd
  6. http://code.alibabatech.com/schema/dubbo
  7. http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
  8. <!-- 提供方应用信息,用于计算依赖关系 -->
  9. <dubbo:application name="test_consumer" />
  10. <!-- 使用zookeeper注册中心暴露服务地址 -->
  11. <dubbo:registry address="zookeeper://172.16.1.37:2181" />
  12. <!-- 用dubbo协议在20880端口暴露服务 -->
  13. <dubbo:protocol name="dubbo" port="20880" />
  14. <!-- 声明需要暴露的服务接口 -->
  15. <dubbo:reference interface="com.dubbo.service.UserService" id="userService" check="false" />
  16. <!-- 声明需要暴露的服务接口 -->
  17. <dubbo:reference interface="com.dubbo.service.TestService" id="testService" check="false" />
  18. <!-- 声明需要暴露的服务接口 -->
  19. <dubbo:reference interface="com.dubbo.service.SeckillService" id="seckillService" check="false" />
  20. </beans>

这里加载一下视图解析器和dubbo配置就好了。


     
     
  1. @Controller
  2. public class UserController {
  3. @Autowired
  4. private UserService userService;
  5. @ResponseBody
  6. @RequestMapping(value = "/list", method = RequestMethod.GET)
  7. public String list(Model model) {
  8. //获取列表页
  9. List list = userService.getListUser();
  10. model.addAttribute( "list", list);
  11. //list.jsp + model = ModelAndView
  12. return "list"; // /WEB-INF/jsp/"list".jsp
  13. }
  14. }

最后另外启动一个tomcat。

访问我们的客户端




最近刚好有点时间,特意来整合一下项目,以后会陆续把前端框架和一些组件也给整合进去,今天就先来整合一下SSM+mysql+dubbo+zookeeper来做一个用户列表功能。关于理论性的知识,大家可以自行查阅下资料,这里重点讲解一下怎么搭建这一套开发环境。

背景

随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

  • 单一应用架构
    • 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。
    • 此时,用于简化增删改查工作量的 数据访问框架(ORM) 是关键。
    • 早期的JSP,ASP,PHP都是把数据操作写在前端,功能相当简单。
  • 垂直应用架构
    • 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。
    • 此时,用于加速前端页面开发的 Web框架(MVC) 是关键。现在很多非互联网公司仍然采用这种架构设计。
  • 分布式服务架构
    • 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
    • 此时,用于提高业务复用及整合的 分布式服务框架(RPC) 是关键。
  • 流动计算架构
    • 当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。
    • 此时,用于提高机器利用率的 资源调度和治理中心(SOA) 是关键。

开发工具:

这里贴出自己的开发工具和版本号,因为有的时候可能会因为版本号而造成很多不必要的冲突。

zookeeper-3.4.6+windows系统+mysql 5.6+jdk7+eclipse+tomcat7+dubbo 2.5.3

zookeeper:

下载zookeeper注册中心,下载地址:http://www.apache.org/dyn/closer.cgi/zookeeper/ 下载后解压即可。


然后进入conf里面,改一下我们的配置,打开zoo.cfg,有得可能不叫这个名字,把zoo_sample.cfg改成zoo.cfg


  
  
  1. clientPort=2181
  2. #server.1=127.0.0.1:3881:4881
  3. #server.2=127.0.0.1:3882:4882
  4. #server.3=127.0.0.1:3883:4883
  5. dataDir=../data
  6. dataLogDir=../log
  7. # The number of milliseconds of each tick
  8. tickTime=10000
  9. # The number of ticks that the initial
  10. # synchronization phase can take
  11. initLimit=10
  12. # The number of ticks that can pass between
  13. # sending a request and getting an acknowledgement
  14. syncLimit=5
  15. # the directory where the snapshot is stored.
  16. # do not use /tmp for storage, /tmp here is just
  17. # example sakes.
  18. #dataDir=../data
  19. #dataLogDir=../dataLog
  20. # the port at which the clients will connect
  21. #clientPort=2181
  22. # the maximum number of client connections.
  23. # increase this if you need to handle more clients
  24. #maxClientCnxns=60
  25. #
  26. # Be sure to read the maintenance section of the
  27. # administrator guide before turning on autopurge.
  28. #
  29. # http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
  30. #
  31. # The number of snapshots to retain in dataDir
  32. #autopurge.snapRetainCount=3
  33. # Purge task interval in hours
  34. # Set to "0" to disable auto purge feature
  35. #autopurge.purgeInterval=1
tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
当这些配置项配置好后,你现在就可以启动 Zookeeper 了,启动后要检查 Zookeeper 是否已经在服务,可以通过 netstat – ano 命令查看是否有你配置的 clientPort 端口号在监听服务。

  • server.A=B:C:D:其中 A 是一个数字,表示这个是第几号服务器;B 是这个服务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。


最后到bin目录下面启动,客户端和服务端。


Dubbo:

需要下载:dubbo-admin-2.5.3的war

然后Tomcat启动一下。这里有两种启动方式,一种是找到自己的tomcat安装目录,替换掉tomcat/webapps下自带的ROOT文件夹内容(即替换tomcat的启动主页),将下载的war包解压到webapps/ROOT中,直接替换即可。

我用的是下面这种,比较简单点。打开eclipse里面的tomcat管理页面。


然后选择第二个,找到自己刚刚下载的war包,部署并且启动一下。

这个时候在浏览器输入自己的ip和端口,我的是localhost:8080


看到这个管理页面就代表成功了。可以来检测我们的消费者和生产者了。

SSM整合:

这里先编写我们的服务端,我把提供服务的统称为服务端,所以这里先创建一个服务端。

所以这里新建一个项目叫做user-service

Maven引入需要的JAR包


   
   
  1. <?xml version="1.0"?>
  2. <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance">
  4. <modelVersion>4.0.0 </modelVersion>
  5. <parent>
  6. <groupId>user </groupId>
  7. <artifactId>user </artifactId>
  8. <version>0.0.1-SNAPSHOT </version>
  9. </parent>
  10. <artifactId>user-service </artifactId>
  11. <packaging>jar </packaging>
  12. <!-- <name>user-service Maven Webapp</name>
  13. <url>http://maven.apache.org</url> -->
  14. <properties>
  15. <project.build.sourceEncoding>UTF-8 </project.build.sourceEncoding>
  16. <!-- 设置 Spring 的版本 -->
  17. <org.springframework.version>4.1.7.RELEASE </org.springframework.version>
  18. </properties>
  19. <dependencies>
  20. <dependency>
  21. <groupId>user-api </groupId>
  22. <artifactId>user-api </artifactId>
  23. <version>0.0.1-SNAPSHOT </version>
  24. </dependency>
  25. <dependency>
  26. <groupId>junit </groupId>
  27. <artifactId>junit </artifactId>
  28. <version>3.8.1 </version>
  29. <scope>test </scope>
  30. </dependency>
  31. <dependency>
  32. <groupId>com.alibaba </groupId>
  33. <artifactId>dubbo </artifactId>
  34. <version>2.5.3 </version>
  35. <exclusions>
  36. <exclusion>
  37. <artifactId>spring </artifactId>
  38. <groupId>org.springframework </groupId>
  39. </exclusion>
  40. </exclusions>
  41. </dependency>
  42. <dependency>
  43. <groupId>org.apache.zookeeper </groupId>
  44. <artifactId>zookeeper </artifactId>
  45. <version>3.4.6 </version>
  46. <exclusions>
  47. <exclusion>
  48. <artifactId>log4j </artifactId>
  49. <groupId>log4j </groupId>
  50. </exclusion>
  51. </exclusions>
  52. </dependency>
  53. <dependency>
  54. <groupId>org.slf4j </groupId>
  55. <artifactId>slf4j-api </artifactId>
  56. <version>1.7.12 </version>
  57. </dependency>
  58. <dependency>
  59. <groupId>ch.qos.logback </groupId>
  60. <artifactId>logback-core </artifactId>
  61. <version>1.1.1 </version>
  62. </dependency>
  63. <!-- 实现slf4j接口并整合 -->
  64. <dependency>
  65. <groupId>ch.qos.logback </groupId>
  66. <artifactId>logback-classic </artifactId>
  67. <version>1.1.1 </version>
  68. </dependency>
  69. <!--2:数据库相关依赖 -->
  70. <dependency>
  71. <groupId>mysql </groupId>
  72. <artifactId>mysql-connector-java </artifactId>
  73. <version>5.1.35 </version>
  74. <scope>runtime </scope>
  75. </dependency>
  76. <dependency>
  77. <groupId>c3p0 </groupId>
  78. <artifactId>c3p0 </artifactId>
  79. <version>0.9.1.2 </version>
  80. </dependency>
  81. <!-- DAO框架:MyBatis依赖 -->
  82. <dependency>
  83. <groupId>org.mybatis </groupId>
  84. <artifactId>mybatis </artifactId>
  85. <version>3.3.0 </version>
  86. </dependency>
  87. <!-- mybats自身实现的spring整合依赖 -->
  88. <dependency>
  89. <groupId>org.mybatis </groupId>
  90. <artifactId>mybatis-spring </artifactId>
  91. <version>1.2.3 </version>
  92. </dependency>
  93. <!-- 3:Servlet web相关依赖 -->
  94. <dependency>
  95. <groupId>taglibs </groupId>
  96. <artifactId>standard </artifactId>
  97. <version>1.1.2 </version>
  98. </dependency>
  99. <dependency>
  100. <groupId>jstl </groupId>
  101. <artifactId>jstl </artifactId>
  102. <version>1.2 </version>
  103. </dependency>
  104. <dependency>
  105. <groupId>com.fasterxml.jackson.core </groupId>
  106. <artifactId>jackson-databind </artifactId>
  107. <version>2.5.4 </version>
  108. </dependency>
  109. <dependency>
  110. <groupId>javax.servlet </groupId>
  111. <artifactId>javax.servlet-api </artifactId>
  112. <version>3.1.0 </version>
  113. </dependency>
  114. <!--4:spring依赖 -->
  115. <!--1)spring核心依赖 -->
  116. <dependency>
  117. <groupId>org.springframework </groupId>
  118. <artifactId>spring-core </artifactId>
  119. <version>${org.springframework.version} </version>
  120. </dependency>
  121. <dependency>
  122. <groupId>org.springframework </groupId>
  123. <artifactId>spring-beans </artifactId>
  124. <version>${org.springframework.version} </version>
  125. </dependency>
  126. <dependency>
  127. <groupId>org.springframework </groupId>
  128. <artifactId>spring-context </artifactId>
  129. <version>${org.springframework.version} </version>
  130. </dependency>
  131. <!--2)spring dao层依赖 -->
  132. <dependency>
  133. <groupId>org.springframework </groupId>
  134. <artifactId>spring-jdbc </artifactId>
  135. <version>${org.springframework.version} </version>
  136. </dependency>
  137. <dependency>
  138. <groupId>org.springframework </groupId>
  139. <artifactId>spring-tx </artifactId>
  140. <version>${org.springframework.version} </version>
  141. </dependency>
  142. <!--3)spring web相关依赖 -->
  143. <dependency>
  144. <groupId>org.springframework </groupId>
  145. <artifactId>spring-web </artifactId>
  146. <version>${org.springframework.version} </version>
  147. </dependency>
  148. <dependency>
  149. <groupId>org.springframework </groupId>
  150. <artifactId>spring-webmvc </artifactId>
  151. <version>${org.springframework.version} </version>
  152. </dependency>
  153. <!-- 4)spring test相关依赖 -->
  154. <dependency>
  155. <groupId>org.springframework </groupId>
  156. <artifactId>spring-test </artifactId>
  157. <version>${org.springframework.version} </version>
  158. </dependency>
  159. <!-- redis客户端:Jedis -->
  160. <dependency>
  161. <groupId>redis.clients </groupId>
  162. <artifactId>jedis </artifactId>
  163. <version>2.7.3 </version>
  164. </dependency>
  165. <!-- protostuff序列化依赖 -->
  166. <dependency>
  167. <groupId>com.dyuproject.protostuff </groupId>
  168. <artifactId>protostuff-core </artifactId>
  169. <version>1.0.8 </version>
  170. </dependency>
  171. <dependency>
  172. <groupId>com.dyuproject.protostuff </groupId>
  173. <artifactId>protostuff-runtime </artifactId>
  174. <version>1.0.8 </version>
  175. </dependency>
  176. <dependency>
  177. <groupId>commons-collections </groupId>
  178. <artifactId>commons-collections </artifactId>
  179. <version>3.2 </version>
  180. </dependency>
  181. <dependency>
  182. <groupId>com.github.sgroschupf </groupId>
  183. <artifactId>zkclient </artifactId>
  184. <version>0.1 </version>
  185. </dependency>
  186. </dependencies>
  187. <!-- <build>
  188. <finalName>user-service</finalName>
  189. </build> -->
  190. </project>

Web.xml

这里使用contextConfigLocation来加载我们spring的配置文件。

   
   
  1. <servlet>
  2. <servlet-name>user-service </servlet-name>
  3. <servlet-class>org.springframework.web.servlet.DispatcherServlet </servlet-class>
  4. <!-- 配置springMVC需要加载的配置文件 spring-dao.xml,spring-service.xml,spring-web.xml
  5. Mybatis -> spring -> springMVC -->
  6. <init-param>
  7. <param-name>contextConfigLocation </param-name>
  8. <param-value>classpath:spring/spring-*.xml </param-value>
  9. </init-param>
  10. </servlet>
  11. <servlet-mapping>
  12. <servlet-name>user-service </servlet-name>
  13. <!-- 默认匹配所有的请求 -->
  14. <url-pattern>/ </url-pattern>
  15. </servlet-mapping>

配置视图解析器:


   
   
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc= "http://www.springframework.org/schema/mvc"
  4. xmlns:context= "http://www.springframework.org/schema/context"
  5. xmlns:dubbo= "http://code.alibabatech.com/schema/dubbo"
  6. xsi:schemaLocation= "http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/mvc
  9. http://www.springframework.org/schema/mvc/spring-mvc.xsd
  10. http://www.springframework.org/schema/context
  11. http://www.springframework.org/schema/context/spring-context.xsd
  12. http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
  13. <!-- 配置SpringMVC -->
  14. <!-- 1:开启SpringMVC注解模式 -->
  15. <!-- 简化配置:
  16. (1)自动注册DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter
  17. (2)提供一系列:数据绑定,数字和日期的format @NumberFormat,@DataTimeFormat,
  18. xml,json默认读写支持.
  19. -->
  20. <mvc:annotation-driven/>
  21. <!--
  22. 2:静态资源默认servlet配置
  23. 1:加入对静态资源的处理:js,gif,png
  24. 2:允许使用"/"做整体映射
  25. -->
  26. <mvc:default-servlet-handler/>
  27. <!--3:配置jsp 显示ViewResolver -->
  28. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  29. <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
  30. <property name="prefix" value="/WEB-INF/jsp/"/>
  31. <property name="suffix" value=".jsp"/>
  32. </bean>
  33. <!--4:扫描web相关的bean -->
  34. <context:component-scan base-package="com.dubbo.controller"/>
  35. </beans>

建立JDBC属性文件

jdbc.properties(文件编码修改为utf-8)


   
   
  1. jdbc.driver=com.mysql.jdbc.Driver
  2. jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
  3. jdbc.username=root
  4. jdbc.password=root

Spring整合mybatis DAO层


   
   
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context= "http://www.springframework.org/schema/context"
  5. xsi:schemaLocation= "http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context.xsd">
  9. <!-- 配置整合mybatis过程 -->
  10. <!-- 1:配置数据库相关参数properties的属性:${url} -->
  11. <context:property-placeholder location="classpath:jdbc.properties"/>
  12. <!-- 2:数据库连接池 -->
  13. <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
  14. <!-- 配置连接池属性 -->
  15. <property name="driverClass" value="${jdbc.driver}"/>
  16. <property name="jdbcUrl" value="${jdbc.url}"/>
  17. <property name="user" value="${jdbc.username}"/>
  18. <property name="password" value="${jdbc.password}"/>
  19. <!-- c3p0连接池的私有属性 -->
  20. <property name="maxPoolSize" value="30"/>
  21. <property name="minPoolSize" value="10"/>
  22. <!-- 关闭连接后不自动commit -->
  23. <property name="autoCommitOnClose" value="false"/>
  24. <!-- 获取连接超时时间 -->
  25. <property name="checkoutTimeout" value="1000"/>
  26. <!-- 当获取连接失败重试次数 -->
  27. <property name="acquireRetryAttempts" value="2"/>
  28. </bean>
  29. <!-- 约定大于配置 -->
  30. <!-- 3:配置SqlSessionFactory对象 -->
  31. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  32. <!-- 注入数据库连接池 -->
  33. <property name="dataSource" ref="dataSource"/>
  34. <!-- 配置MyBatis全局配置文件:mybatis-config.xml -->
  35. <property name="configLocation" value="classpath:mybatis-config.xml"/>
  36. <!-- 扫描entity包 使用别名 -->
  37. <property name="typeAliasesPackage" value="com.dubbo.entity"/>
  38. <!-- 扫描sql配置文件:mapper需要的xml文件 -->
  39. <property name="mapperLocations" value="classpath:mapper/*.xml"/>
  40. </bean>
  41. <!-- 4:配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中-->
  42. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
  43. <!-- 注入sqlSessionFactory -->
  44. <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
  45. <!-- 给出需要扫描Dao接口包 -->
  46. <property name="basePackage" value="com.dubbo.dao"/>
  47. </bean>
  48. <!-- RedisDao -->
  49. <bean id="redisDao" class="com.dubbo.dao.cache.RedisDao">
  50. <constructor-arg index="0" value="localhost"/>
  51. <constructor-arg index="1" value="6379"/>
  52. </bean>
  53. </beans>
redisDao以后会用到,现在先不管。

spring整合service层,开启事务


   
   
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context= "http://www.springframework.org/schema/context"
  5. xmlns:tx= "http://www.springframework.org/schema/tx"
  6. xsi:schemaLocation= "http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/context
  9. http://www.springframework.org/schema/context/spring-context.xsd
  10. http://www.springframework.org/schema/tx
  11. http://www.springframework.org/schema/tx/spring-tx.xsd">
  12. <!-- 扫描service包下所有使用注解的类型 -->
  13. <context:component-scan base-package="com.dubbo.service"/>
  14. <!-- 配置事务管理器 -->
  15. <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  16. <!-- 注入数据库连接池 -->
  17. <property name="dataSource" ref="dataSource"/>
  18. </bean>
  19. <!-- 配置基于注解的声明式事务
  20. 默认使用注解来管理事务行为
  21. -->
  22. <tx:annotation-driven transaction-manager="transactionManager"/>
  23. <!-- 具体的实现bean -->
  24. </beans>

mybatis配置文件


   
   
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <!-- 配置全局属性 -->
  7. <settings>
  8. <!-- 使用jdbc的getGeneratedKeys 获取数据库自增主键值 -->
  9. <setting name="useGeneratedKeys" value="true"/>
  10. <!-- 使用列别名替换列名 默认:true
  11. select name as title from table
  12. -->
  13. <setting name="useColumnLabel" value="true"/>
  14. <!-- 开启驼峰命名转换:Table(create_time) -> Entity(createTime) -->
  15. <setting name="mapUnderscoreToCamelCase" value="true"/>
  16. </settings>
  17. </configuration>
基本上配置就这些,log4我感觉用处不大,懒得配置了。下面还有有一些mybatis的xml配置,这个后面再讲。

mysql:

创建我们的sql


   
   
  1. CREATE TABLE `user` (
  2. `userId` BIGINT ( 20),
  3. `userName` VARCHAR ( 108),
  4. `account` VARCHAR ( 108),
  5. `password` VARCHAR ( 108),
  6. `phone` VARCHAR ( 66),
  7. `address` VARCHAR ( 108)
  8. ); DEFAULT CHARSET=utf8;

简单创建几个字段,随便加几条数据就好。

创建实体类:

在创建实体类之前我先把包结构给建立好了;


在我们的entity里面创建一下User的实体类。


   
   
  1. public class User implements Serializable{
  2. private String userId;
  3. private String userName;
  4. private String account;
  5. private String phone;
  6. private String password;
  7. private String address;
  8. public String getUserId() {
  9. return userId;
  10. }
  11. public void setUserId(String userId) {
  12. this.userId = userId;
  13. }
  14. public String getUserName() {
  15. return userName;
  16. }
  17. public void setUserName(String userName) {
  18. this.userName = userName;
  19. }
  20. public String getAccount() {
  21. return account;
  22. }
  23. public void setAccount(String account) {
  24. this.account = account;
  25. }
  26. public String getPhone() {
  27. return phone;
  28. }
  29. public void setPhone(String phone) {
  30. this.phone = phone;
  31. }
  32. public String getAddress() {
  33. return address;
  34. }
  35. public void setAddress(String address) {
  36. this.address = address;
  37. }
  38. public String getPassword() {
  39. return password;
  40. }
  41. public void setPassword(String password) {
  42. this.password = password;
  43. }
  44. }

编写dao和service


   
   
  1. public interface UserDao {
  2. public List<User> getListUser();
  3. }


   
   
  1. public interface UserService {
  2. public List<User> getListUser();
  3. }


   
   
  1. @Service
  2. public class UserServiceImpl implements UserService {
  3. private final Logger logger = LoggerFactory.getLogger( this.getClass());
  4. //注入Service依赖
  5. @Autowired
  6. private UserDao userDao;
  7. /**
  8. * @return
  9. * @see com.dubbo.service.UserService#getListUser()
  10. *<pre>
  11. *<li>Author:</li>
  12. *<li>Date: 2016年9月23日</li>
  13. *</pre>
  14. */
  15. @Override
  16. public List<User> getListUser() {
  17. return userDao.getListUser();
  18. }
  19. }


   
   
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.dubbo.dao.UserDao">
  6. <!-- 目的:为DAO接口方法提供sql语句配置-->
  7. <select id="getListUser" resultType="User">
  8. SELECT*FROM USER
  9. </select>
  10. </mapper>

编写Controller


   
   
  1. @Autowired
  2. private UserService userService;
  3. @RequestMapping(value = "/list", method = RequestMethod.GET)
  4. public String list(Model model) {
  5. //获取列表页
  6. List<User> list = userService.getListUser();
  7. model.addAttribute( "list", list);
  8. //list.jsp + model = ModelAndView
  9. return "list"; // /WEB-INF/jsp/"list".jsp
  10. }

启动Tomcat测试:


整合Dubbo和zookeeper

在整合之前首先要明白Dubbo和zookeeper是干嘛用的。

SOA的框架也正是现在网站的系统架构演化史,也从侧面反映了我国网民数量的增加和对网站性能的提升。

大型网站系统特点

  (1)高并发、大流量:PV量巨大

  (2)高可用:7*24小时不间断服务

  (3)海量数据:文件数目分分钟xxTB

  (4)用户分布广泛,网络情况复杂:网络运营商

  (5)安全环境恶劣:黑客的攻击

  (6)需求快速变更,发布频繁:快速适应市场,满足用户需求

  (7)渐进式发展:慢慢地运营出大型网站


例子:

小明作为一个屌丝码农,有一天创建了一个网站,最开始只是小明一个人在运营,所有的程序都在一个Server里面跑,数据库访问和逻辑控制也都写在jsp文件里面。应用程序、数据库、文件等所有资源都集中在一台Server上。这就是典型的纯jsp网站。



后来他的好朋友小王来了,他觉得小明的网站做的不错,于是就提出了改造建议,小王可是受过培训的啊,什么MVC人家可是经常背,于是他们的网站就开始拆分MVC三层了。并且把文件服务器和数据库单独部署到一个Server上。

这个时候三台Server平天下,应用和数据服务分离。



再到后来,他们的网站越来越大了,普通的架构已经满足不了他们了,怎么办,必须得做集群,必须要有缓存,什么读写分离啊,redis啊和反向代理和CDN加速等等,慢慢的开始应用起来。

分布式服务:既然每一个应用系统都需要执行许多相通的业务操作,比如用户管理、商品管理等,那么可以将这些共用的业务提取出来,独立部署。


好了,其实dubbo简单来说就是用来管理我们的服务的,以前我们都是自己调自己的服务,如果服务挂掉的话,那么整个系统就挂掉了,现在是我们把服务交给dubbo去统一管理,而zookeeper是管理我们的dubbo的。

创建user-api;user-api的作用很简单,作为一个API,把接口暴露出来供我们的客户端调用。


   
   
  1. public interface UserService {
  2. public List getListUser();
  3. }
修改服务端代码,这里要修改一下我们的user-service。把他作为一个服务层,只和数据库进行交互。

Web-xml


   
   
  1. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
  3. http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  4. version="3.1" metadata-complete="true">
  5. <!-- 修改servlet版本为3.1 -->
  6. <!-- 配置DispatcherServlet -->
  7. <listener>
  8. <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  9. </listener>
  10. <context-param>
  11. <param-name>contextConfigLocation</param-name>
  12. <param-value>classpath:spring/spring-*.xml</param-value>
  13. </context-param>
  14. <servlet>
  15. <servlet-name>user-service</servlet-name>
  16. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  17. <!-- 配置springMVC需要加载的配置文件 spring-dao.xml,spring-service.xml,spring-web.xml
  18. Mybatis -> spring -> springMVC -->
  19. <init-param>
  20. <param-name>contextConfigLocation</param-name>
  21. <param-value>classpath:spring/spring-*.xml</param-value>
  22. </init-param>
  23. </servlet>
  24. <servlet-mapping>
  25. <servlet-name>user-service</servlet-name>
  26. <!-- 默认匹配所有的请求 -->
  27. <url-pattern>/</url-pattern>
  28. </servlet-mapping>
  29. </web-app>
这里如果不用<listener>加载的话dubbo服务注册不上去,具体原因还没有找到,还有这里加载了两遍配置文件才起作用,具体原因也还在探索中(迷茫。。)最后一个拦截器,可以不需要,因为我们不通过user-service访问页面。
去掉service接口,这里我们通过引入user-api里面的接口,并且也基础里面的接口,所以user-service里面的接口可以去掉。

创建dubbo配置文件 spring-dubbo.xml


   
   
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:p= "http://www.springframework.org/schema/p"
  4. xmlns:dubbo= "http://code.alibabatech.com/schema/dubbo"
  5. xsi:schemaLocation= "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
  6. http://code.alibabatech.com/schema/dubbo
  7. http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
  8. <!-- 提供方应用信息,用于计算依赖关系 -->
  9. <dubbo:application name="test_provider" />
  10. <!-- 使用zookeeper注册中心暴露服务地址 -->
  11. <dubbo:registry address="zookeeper://172.16.1.37:2181" />
  12. <!-- 用dubbo协议在20880端口暴露服务 -->
  13. <dubbo:protocol name="dubbo" port="20880" />
  14. <!-- 声明需要暴露的服务接口 -->
  15. <dubbo:service interface="com.dubbo.service.UserService" ref="userService" />
  16. <!-- 具体的实现bean -->
  17. <bean id="userService" class="com.dubbo.service.impl.UserServiceImpl" />
  18. <!-- 声明需要暴露的服务接口 -->
  19. <dubbo:service interface="com.dubbo.service.TestService" ref="testService" />
  20. <!-- 具体的实现bean -->
  21. <bean id="testService" class="com.dubbo.service.impl.TestServiceImpl" />
  22. <!-- 声明需要暴露的服务接口 -->
  23. <dubbo:service interface="com.dubbo.service.SeckillService" ref="seckillService" />
  24. <!-- 具体的实现bean -->
  25. <bean id="seckillService" class="com.dubbo.service.impl.SeckillServiceImpl" />
  26. </beans>

最后启动Tomcat;

我们使用zk-Inspector,来监控一下zk的服务。



点击绿色的箭头,然后开启监控,我们可以看到

dubbo服务已经注册成功,然后我们再进入dubbo管理页面看看。


也创建了三个服务,证明我们的服务端已经开发完成。

客户端:

这个时候要创建我们的客户端了,客户端也采用SSM架构,其实根本不用Mybatis,因为数据交互都交给了我们的客户端,这里直接把服务端的架构复制过来;

   
   
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo= "http://code.alibabatech.com/schema/dubbo"
  4. xsi:schemaLocation= "http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd
  6. http://code.alibabatech.com/schema/dubbo
  7. http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
  8. <!-- 提供方应用信息,用于计算依赖关系 -->
  9. <dubbo:application name="test_consumer" />
  10. <!-- 使用zookeeper注册中心暴露服务地址 -->
  11. <dubbo:registry address="zookeeper://172.16.1.37:2181" />
  12. <!-- 用dubbo协议在20880端口暴露服务 -->
  13. <dubbo:protocol name="dubbo" port="20880" />
  14. <!-- 声明需要暴露的服务接口 -->
  15. <dubbo:reference interface="com.dubbo.service.UserService" id="userService" check="false" />
  16. <!-- 声明需要暴露的服务接口 -->
  17. <dubbo:reference interface="com.dubbo.service.TestService" id="testService" check="false" />
  18. <!-- 声明需要暴露的服务接口 -->
  19. <dubbo:reference interface="com.dubbo.service.SeckillService" id="seckillService" check="false" />
  20. </beans>

这里加载一下视图解析器和dubbo配置就好了。


   
   
  1. @Controller
  2. public class UserController {
  3. @Autowired
  4. private UserService userService;
  5. @ResponseBody
  6. @RequestMapping(value = "/list", method = RequestMethod.GET)
  7. public String list(Model model) {
  8. //获取列表页
  9. List list = userService.getListUser();
  10. model.addAttribute( "list", list);
  11. //list.jsp + model = ModelAndView
  12. return "list"; // /WEB-INF/jsp/"list".jsp
  13. }
  14. }

最后另外启动一个tomcat。

访问我们的客户端




猜你喜欢

转载自blog.csdn.net/weixin_40902527/article/details/85091727