企业级应用,如何实现服务化五(dubbo综合案例)
这是企业级应用,如何实现服务化第五篇。在上一篇企业级应用,如何实现服务化四(基础环境准备)中。已经准备好了zookeeper注册中心,和dubbo管理控制台。这一篇通过一个综合案例,看一看在企业级应用中,如何将dubbo整合应用起来。
1.案例架构
项目模块说明:
#描述项目模块: 1.父/聚合项目:spring-dubbo-master 统一管理依赖版本信息,用于快速构建各个项目模块 2.实体类子项目:spring-dubbo-domain 用于放置实体类 3.持久层子项目:spring-dubbo-dao 用于放置持久层dao 4.业务层子项目:spring-dubbo-service 用于放置业务层service实现类 5.web层子项目:spring-dubbo-web 用于放置表现层Controller,以及表现层资源 6.公共接口层项目:spring-dubbo-interface 用于放置公共服务接口,把公共接口抽象出来,方便业务层和web层引用
2.服务器规划
3.创建项目模块
3.1.创建父/聚合项目
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.anan</groupId> <artifactId>spring-dubbo-master</artifactId> <version>1.0-SNAPSHOT</version> <!--父项目,聚合项目打包方式设置为pom--> <packaging>pom</packaging> <!--聚合其他模块--> <modules> <module>spring-dubbo-domain</module> <module>spring-dubbo-dao</module> <module>spring-dubbo-interface</module> <module>spring-dubbo-service</module> <module>spring-dubbo-web</module> </modules> <!--统一管理依赖版本--> <properties> <!--spring 版本--> <spring.version>5.0.2.RELEASE</spring.version> <!-- log4j日志包版本 --> <slf4j.version>1.7.7</slf4j.version> <log4j.version>1.2.17</log4j.version> <!-- jstl标签版本 --> <jstl.version>1.2</jstl.version> <!--servlet版本--> <servlet.version>2.5</servlet.version> <!--jsp版本--> <jsp.version>2.0</jsp.version> <!-- mybatis版本号 --> <mybatis.version>3.4.5</mybatis.version> <!--mysql驱动版本--> <mysql.version>5.1.30</mysql.version> <!-- mybatis-spring整合包版本 --> <mybatis.spring.version>1.3.1</mybatis.spring.version> <!--druid版本--> <druid.version>1.0.29</druid.version> <!-- aspectj版本号 --> <aspectj.version>1.6.12</aspectj.version> <!--dubbo相关版本号--> <dubbo.version>2.7.0</dubbo.version> <zookeeper.version>3.4.7</zookeeper.version> <zkclient.version>0.1</zkclient.version> <curator.version>2.11.1</curator.version> </properties> <!--统一管理依赖--> <dependencyManagement> <dependencies> <!--spring依赖包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!-- spring web包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!-- spring mvc包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!--spring jdbc包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <!--spring tx包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <!--aspectj包--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${aspectj.version}</version> </dependency> <!-- jstl标签类 --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>${jstl.version}</version> </dependency> <!--servlet依赖--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>${servlet.version}</version> <scope>provided</scope> </dependency> <!--jsp依赖--> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>${jsp.version}</version> <scope>provided</scope> </dependency> <!-- mybatis核心包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!-- mybatis-spring整合包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>${mybatis.spring.version}</version> </dependency> <!-- mysql数据库依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> <scope>runtime</scope> </dependency> <!--数据库连接池druid--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency> <!-- log4j包 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <!--dubbo相关依赖--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>${dubbo.version}</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>${zookeeper.version}</version> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>${zkclient.version}</version> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>${curator.version}</version> </dependency> </dependencies> </dependencyManagement> </project>
3.2.创建实体类子项目
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>spring-dubbo-master</artifactId> <groupId>com.anan</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-dubbo-domain</artifactId> <packaging>jar</packaging> </project>
3.3.创建持久层子项目
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>spring-dubbo-master</artifactId> <groupId>com.anan</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-dubbo-dao</artifactId> <packaging>jar</packaging> <!--配置依赖--> <dependencies> <!--依赖domain--> <dependency> <groupId>com.anan</groupId> <artifactId>spring-dubbo-domain</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--依赖数据库驱动包--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!--依赖数据库连接池包--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> <!--依赖mybatis框架包--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> </dependency> <!--mybatis-spring整合包--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> </dependency> </dependencies> </project>
3.4.创建公共接口项目
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>spring-dubbo-master</artifactId> <groupId>com.anan</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-dubbo-interface</artifactId> <packaging>jar</packaging> <!--配置依赖--> <dependencies> <!--依赖domain--> <dependency> <groupId>com.anan</groupId> <artifactId>spring-dubbo-domain</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
3.5.创建业务层子项目
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>spring-dubbo-master</artifactId> <groupId>com.anan</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-dubbo-service</artifactId> <packaging>war</packaging> <!--配置依赖--> <dependencies> <!--依赖interface--> <dependency> <groupId>com.anan</groupId> <artifactId>spring-dubbo-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--依赖dao--> <dependency> <groupId>com.anan</groupId> <artifactId>spring-dubbo-dao</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--依赖spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> <!--依赖dubbo--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> </dependency> <!--log4j日志依赖--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> </dependencies> <build> <finalName>spring-dubbo-service</finalName> </build> </project>
3.6.创建web层子项目
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>spring-dubbo-master</artifactId> <groupId>com.anan</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>spring-dubbo-web</artifactId> <packaging>war</packaging> <!--配置依赖--> <dependencies> <!--依赖interface--> <dependency> <groupId>com.anan</groupId> <artifactId>spring-dubbo-interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--依赖spring--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <!--依赖servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <scope>provided</scope> </dependency> <!--依赖jsp--> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <scope>provided</scope> </dependency> <!--依赖jstl--> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> </dependency> <!--依赖dubbo--> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </dependency> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> </dependency> <dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> </dependency> <!--log4j日志依赖--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> </dependencies> <build> <finalName>spring-dubbo-web</finalName> </build> </project>
3.7.业务层子项目开发
3.7.1.service实现类
package com.anan.service.impl; import com.anan.dao.UserDao; import com.anan.po.User; import com.anan.service.UserService; import org.apache.dubbo.config.annotation.Service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service(timeout = 8000) public class UserServiceImpl implements UserService { // 定义用户dao @Autowired private UserDao userDao; /** * 查询用户列表 */ public List<User> findAllUsers() { System.out.println("【findAllUsers】"); return userDao.findAllUsers(); } /** * 根据用户Id查询用户 * * @param userId */ public User findUserByUserId(Long userId) { System.out.println("【findUserByUserId】方法执行中......id="+userId); return userDao.findUserByUserId(userId); } /** * 更新用户 * * @param user */ @Transactional(propagation = Propagation.REQUIRED,readOnly = false) public void updateUser(User user) { System.out.println("【updateUser】方法执行中......"); userDao.updateUser(user); } /** * 查看用户详情信息 * * @param userId */ public User findUserDetailByUserId(Long userId) { System.out.println("【findUserDetailByUserId】方法执行中......id="+userId); return userDao.findUserDetailByUserId(userId); } }
3.7.2.核心配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!--提供方应用信息,用于计算依赖关系--> <dubbo:application name="spring-dubbo-service" /> <!--使用zookeeper注册中心--> <dubbo:registry address="zookeeper://192.168.80.100:2181,192.168.80.101:2181,192.168.80.102:2181" file="${catalina.home}/dubbo-registry/dubbo-registry.properties" /> <!--用dubbo协议在20885端口暴露服务--> <dubbo:protocol name="dubbo" port="20885"></dubbo:protocol> <!--扫描service包--> <dubbo:annotation package="com.anan.service.impl" /> </beans>
3.8.web层子项目开发
3.8.1.Controller控制器
package com.anan.controller; import com.anan.po.User; import com.anan.service.UserService; import org.apache.dubbo.config.annotation.Reference; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import java.util.List; /** * 用户controller */ @Controller public class UserController { // 定义用户service @Reference private UserService userService; /** * 查询用户列表数据 */ @RequestMapping("/list.do") public String list(Model model){ // 查询用户列表 List<User> userList = userService.findAllUsers(); model.addAttribute("userList",userList); return "user/list"; } /** * 根据用户id查询用户 */ @RequestMapping("/get.do") public String get(Model model,Long id){ // 根据用户Id查询用户 User user = userService.findUserByUserId(id); model.addAttribute("user",user); return "user/edit"; } /** * 保存修改用户信息 */ @RequestMapping("/edit.do") public String edit(User user){ // 更新保存用户信息 userService.updateUser(user); return "redirect:/list.do"; } /** * 查看用户详情信息 */ @RequestMapping("/show.do") public String show(Model model,Long id){ // 查看用户详情信息 User user = userService.findUserDetailByUserId(id); model.addAttribute("user",user); return "user/show"; } }
3.8.2.核心配置
<?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://dubbo.apache.org/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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!--配置包扫描controller--> <context:component-scan base-package="com.anan.controller"/> <!--注解驱动方式配置处理器映射器和处理器适配器--> <mvc:annotation-driven></mvc:annotation-driven> <!--配置视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--配置前缀:页面的公共目录路径--> <property name="prefix" value="/WEB-INF/jsp/"></property> <!--配置后缀:页面的扩展名称--> <property name="suffix" value=".jsp"></property> </bean> <!--消费方应用信息,用于计算依赖关系--> <dubbo:application name="spring-dubbo-web"/> <!--使用zookeeper注册中心--> <dubbo:registry address="zookeeper://192.168.80.100:2181,192.168.80.101:2181,192.168.80.102:2181" file="../dubbo-registry/dubbo-registry.properties"/> <!--配置包扫描controller中Reference--> <dubbo:annotation package="com.anan.controller"/> </beans>
4.项目部署
说明:将项目打包,部署到tomcat。
4.1.node02节点
tomcat_1:
tomcat_2:
4.2.node03节点
tomcat_1:
5.测试
说明:启动tomcat,进行测试。
5.1.dubbo管理控制台
5.1.1.服务提供者
5.1.2.服务消费者
5.2.访问服务
5.3.service服务后台执行日志
6.小结
通过综合案例,实现了一个完整的高可用、负载均衡的web应用。按照项目三层架构:web层-->业务层service-->持久层dao。其中:
web应用高可用、负载均衡方案: 1.nginx:keepalive,DNS轮询 2.web层:nginx,F5 3.service层:微服务框架,dubbo或者spring cloud 4.dao层:主备+读写分离,可选择通过mycat中间件实现(后续专门针对dao层高可用,写一个系列)
我们唯一能够控制的是自己的脾气和努力