e3mall商城的归纳总结2之认识dubbo、zookeeper

由于本项目用的是soa架构,因此必须需要两个系统之间进行通信,目前的解决办法有三种(本人认为)

  • Webservice:效率不高基于soap协议。项目中不推荐使用。
  • 使用restful形式的服务:http+json。很多项目中应用。如果服务太多,服务之间调用关系混乱,需要治疗服务。
  • 使用dubbo。使用rpc协议进行远程调用,直接使用socket通信。传输效率高,并且可以统计出系统之间的调用关系、调用次数。(阿里巴巴的技术推荐使用)

一、什么是dubbo?

Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成
Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
重要的是可以和spring无缝集成,也就是说在spring里可以不添加任何jar包就可以使用dubbo了。
下面这个图就是dubbo官网上的图
在这里插入图片描述
节点角色说明:
Provider: 暴露服务的服务提供方。
Consumer: 调用远程服务的服务消费方。
Registry: 服务注册与发现的注册中心。
Monitor: 统计服务的调用次调和调用时间的监控中心。
Container: 服务运行容器。
在本项目中
provider服务的提供方是我们的service
consumer服务的消费方为controller层,也就是web层。

二、什么是zookeeper(动物园管理员)?

既然说到dubbo了,那么service层暴露了自己的接口,Web层想要连接这个接口该如何实现呢?
首先我们肯定需要在配置文件中引入interface层,让该接口加载到spring容器中(IOC),这样方便我们使用。服务层和Web层的都有了,那我们该如何把他们连接起来呢,在这里dubbo官网推荐使用zookeeper,(相当于一个中介,服务层相当于房主,我这里有房,需要去中介那里说一声在什么位置,而Web层相当于租客,租客想要租房去中介了解位置,然后就可以准确的到达房主的屋子。)

为什么起名为动物园管理员呢?

动物园里有好多的动物,游客可以根据动物园管理员提供的向导图到不同的场馆观赏各种类型的动物,而不是像走在原始丛林里,心惊胆颤的被动物所观赏。为了让各种不同的动物呆在它们应该呆的地方,而不是相互串门,或是相互厮杀,就需要动物园管理员按照动物的各种习性加以分类和管理,这样我们才能更加放心安全的观赏动物。
其实zookeeper的功能很多,但是这里我们只用到了它的分布式系统的功能。

安装zookeeper(zk)

安装环境:
Linux:centos6.4
Jdk:1.7以上版本
安装前提条件:Zookeeper是java开发的可以运行在windows、linux环境。需要先安装jdk。
安装步骤:
第一步:安装jdk
第二步:把zookeeper的压缩包上传到linux系统。
第三步:解压缩压缩包
tar -zxvf zookeeper-3.4.6.tar.gz
第四步:进入zookeeper-3.4.6目录,创建data文件夹。
第五步:把zoo_sample.cfg改名为zoo.cfg
[root@localhost conf]# mv zoo_sample.cfg zoo.cfg
第六步:修改data属性:dataDir=/root/zookeeper-3.4.6/data
第七步:启动zookeeper
[root@localhost bin]# ./zkServer.sh start
关闭:[root@localhost bin]# ./zkServer.sh stop
查看状态:[root@localhost bin]# ./zkServer.sh status

注意:需要关闭防火墙。
service iptables stop
永久关闭修改配置开机不启动防火墙:
chkconfig iptables off
如果不能成功启动zookeeper,需要删除data目录下的zookeeper_server.pid文件。

服务层的resource目录下application-service.xml
这里我把zookeeper安装到虚拟机(192.168.25.110)上了

<?xml version="1.0" encoding="UTF-8"?>
<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:dubbo="http://code.alibabatech.com/schema/dubbo" 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
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
	http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
	
	<context:component-scan base-package="cn.tsu.e3mall.service"/>
	
	<!-- 使用dubbo发布服务 -->
	<!-- 提供方应用信息,用于计算依赖关系 -->
	<dubbo:application name="e3mall-manger" />
	<dubbo:registry protocol="zookeeper"
		address="192.168.25.110:2181" />
	<!-- 用dubbo协议在20880端口暴露服务 -->
	<dubbo:protocol name="dubbo" port="20880" />
	<!-- 声明需要暴露的服务接口 -->
	<dubbo:service interface="cn.tsu.e3mall.service.ItemService" ref="itemServiceImpl" />
	<dubbo:service interface="cn.tsu.e3mall.service.ItemCatService" ref="itemCatServiceImpl" />
</beans>

这里我创建了两个service服务接口,ref=“XXXXImpl”指的是该服务的实现类。
都是留controller层调用的。而XXXXImpl是通过component-scan(<context:component-scan base-package=“cn.tsu.e3mall.service”/>)进行扫描自动注册到spring容器中。

<!-- 声明需要暴露的服务接口 -->
	<dubbo:service interface="cn.tsu.e3mall.service.ItemService" ref="itemServiceImpl" />
	<dubbo:service interface="cn.tsu.e3mall.service.ItemCatService" ref="itemCatServiceImpl" />

Web层的spring下的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:p="http://www.springframework.org/schema/p" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
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.2.xsd 
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd 
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd 
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">

	<!-- 扫描自动注册cn.tsu.e3mall.controller下的包 -->
	<context:component-scan base-package="cn.tsu.e3mall.controller" />
	<!-- 加载classpath目录下client.properties配置文件 -->
	<context:property-placeholder location="classpath:client.properties"/>
	
	<!-- 定义文件上传解析器 -->
	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 设定默认编码 -->
		<property name="defaultEncoding" value="UTF-8"></property>
		<!-- 设定文件上传的最大值5MB,5*1024*1024 -->
		<property name="maxUploadSize" value="5242880"></property>
	</bean>
	
	<mvc:annotation-driven />
	<!-- 对静态资源放行 -->
	<!-- <mvc:resources location="/css/" mapping="/css/**" />
	<mvc:resources location="/js/" mapping="/js/**" /> --> 
	<mvc:default-servlet-handler/>
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
	<!-- 引用dubbo服务 -->
	<dubbo:application name="e3mall-manger-web"/> 
	<dubbo:registry protocol="zookeeper" address="192.168.25.110:2181"/>	
	<dubbo:reference interface="cn.tsu.e3mall.service.ItemService" id="itemService"  timeout="300000"/>
	<dubbo:reference interface="cn.tsu.e3mall.service.ItemCatService" id="itemCatService"  timeout="300000"/>
	<dubbo:reference interface="cn.tsu.content.e3mall.service.ContentCatService" id="contentCatService"  timeout="300000"/>
	<dubbo:reference interface="cn.tsu.content.e3mall.service.ContentService" id="contentService"  timeout="300000"/>
	<dubbo:reference interface="cn.tsu.search.e3mall.service.SearchService" id="searchService"  timeout="300000"/>
</beans>

三、pagehelper分页技术

项目中的代码如下:

@Override
	public EasyUiDateGirdResult findTbItems(Integer page, Integer rows) {
	    //获取第page页,rows条内容
		PageHelper.startPage(page, rows); 
		//紧跟着的第一个select方法会被分页
		TbItemExample example = new TbItemExample();
		List<TbItem> list = TbItemMapper.selectByExample(example);
		//PageInfo对象里包含了list的各种属性进行赋值到pageinfo中
		PageInfo<TbItem> pageInfo = new PageInfo<>(list);
		//创建返回对象并赋值
		EasyUiDateGirdResult easy = new  EasyUiDateGirdResult();
		easy.setTotal(pageInfo.getTotal());
		easy.setRows(list);
		return easy;
	}
学习pagehelper技术
第一步:在Mybatis配置xml中配置拦截器插件:
<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageHelper">
        <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库-->        
        <property name="dialect" value="mysql"/>
    </plugin>
</plugins>
第二步:在代码中使用
1、设置分页信息:
    //获取第1页,10条内容,默认查询总数count
    PageHelper.startPage(1, 10);

    //紧跟着的第一个select方法会被分页
List<Country> list = countryMapper.selectIf(1);
2、取分页信息
//分页后,实际返回的结果list类型是Page<E>,如果想取出分页信息,需要强制转换为Page<E>,
Page<Country> listCountry = (Page<Country>)list;
listCountry.getTotal();
3、取分页信息的第二种方法
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectAll();
//用PageInfo对结果进行包装
PageInfo page = new PageInfo(list);

项目中代码用的是第二种方法

四、安装maven工程跳过测试

clean install -DskipTests

posted @ 2019-01-17 18:53  拉风的小锋  阅读(177)  评论(0编辑  收藏  举报