一.课程计划
1 | 第二天:商品列表功能实现 |
二.拆分工程
之前我们说过要将这个项目拆分成soa架构,什么事soa架构,soa架构就是面向服务,就是将我们的项目拆分成服务层和表现层。所以我目前需要将web层与dao和Service层拆开。
- 首先在idea中我们在web层的父工程也就是e3_manager中的pom文件中的
中删掉其子模块也就是web层(e3_manager_web)
- 这个时候web层就消失了,然后主要剩下了dao层和Service层,那么现在我们是将服务层(dao+service)和表现层(web)拆分成两个系统,那么服务层最终也需要部署到服务器上,所以需要一个打包成war包的项目,而现在的dao和Service都是jar包,所以我们将Service的打包方式改为war
- 因为是两个系统,所以web层应该和manager和common属于同一个层次,所以我们引进web层
- 修改web层中父模块,
,原来是manager模块,现在直接改为parent,修改完后,效果如下
- 上述完成之后呢,我们来看看web层(e3_manager_web)的pom文件
1 | <?xml version="1.0" encoding="UTF-8"?> |
看,是不是其中有依赖Service的,那么我想一想,我们现在如果这么依赖Service,相当于就是将Service打包成jar包依赖过来,那么我们现在是要将系统分开的吖,所以不能这么依赖,我们只需要依赖接口就行了,Service相当于是我们这个项目的接口的实现类,所以如果我们依赖实现类,那么跟之前就没什么区别了
- 当我们这样做之后,打开我们之前写的类,发现报错了,这是为什么呢?(看下图)
所以我们需要将spring的依赖复制过来,就是将Service中spring的依赖复制过来就行,简单的一匹
- 接下来呢,我们继续拆分,之前我们是将配置文件全部放在了web层的,那我们来想想,既然我们都把工程拆开了,是不是不能将配置文件全放在web层了
- Service需要conf和mybatis和spring,不需要springmvc,web.xml文件也只需部分(看图片)
- Web层需要的东西看下图;
三.将工程改造为SOA架构
3.1 分析:
由于宜立方商城是基于soa的架构,表现层和服务层是不同的工程。所以要实现商品列表查询需要两个系统之间进行通信。
如何实现远程通信?
1、Webservice:效率不高基于soap协议。项目中不推荐使用。
2、使用restful形式的服务:http+json。很多项目中应用。如果服务太多,服务之间调用关系混乱,需要治疗服务。(说白了就是在url地址栏中加参数,如京东)
3、使用dubbo。使用rpc协议进行远程调用,直接使用socket通信。传输效率高,并且可以统计出系统之间的调用关系、调用次数。
==rpc协议:远程过程调用==
中间有个Dubbo中间件,用于控制服务调用,而不是向上面图中一样,直接去连线,而是先连中间件,这样就好管理了许多
3.2 dubbo:
3.2.1 什么是dubbo?
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。
单一应用架构
- 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。
- 此时,用于简化增删改查工作量的 数据访问框架(ORM) 是关键。
- 垂直应用架构
- 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。
- 此时,用于加速前端页面开发的 Web框架(MVC) 是关键。
- 分布式服务架构
- 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
- 此时,用于提高业务复用及整合的 分布式服务框架(RPC) 是关键。
- 流动计算架构
- 当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时==需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率==。
- 此时,用于提高机器利用率的 资源调度和治理中心(SOA) 是关键。
Dubbo就是资源调度和治理中心的管理工具。
3.2.2 Dubbo的架构
节点角色说明:
- Provider: 暴露服务的服务提供方。
- Consumer: 调用远程服务的服务消费方。
- Registry: 服务注册与发现的注册中心。
- Monitor: 统计服务的调用次调和调用时间的监控中心。
- Container: 服务运行容器。
调用关系说明:
- 0: 服务容器负责启动,加载,运行服务提供者.
- 1: 服务提供者在启动时,向注册中心注册自己提供的服务。
- 2: 服务消费者在启动时,向注册中心订阅自己所需的服务。
- 3: 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
- 4: 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
- 5: 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
3.2.3 使用方法
Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用Spring加载Dubbo的配置即可,Dubbo基于Spring的Schema扩展进行加载。
单一工程中spring的配置:
1 | <bean id="xxxService" class="com.xxx.XxxServiceImpl" /> |
远程服务:
在本地服务的基础上,只需做简单配置,即可完成远程化:
将上面的local.xml配置拆分成两份,将服务定义部分放在服务提供方remote-provider.xml,将服务引用部分放在服务消费方remote-consumer.xml。
并在提供方增加暴露服务配置dubbo:service,在消费方增加引用服务配置dubbo:reference。
发布服务:
1 | <!-- 和本地服务一样实现远程服务 --> |
调用服务:
1 | <!-- 增加引用远程服务配置 --> |
3.3 注册中心:
3.3.1 Zookeeper(Apacher旗下的,Java开发)介绍
官方推荐使用zookeeper注册中心。
注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小。使用dubbo-2.3.3以上版本,建议使用zookeeper注册中心。
Zookeeper是Apacahe Hadoop的子项目,是一个树型的目录服务,支持变更推送,适合作为Dubbo服务的注册中心,工业强度较高,可用于生产环境,并推荐使用
Zookeeper:
1、可以作为集群的管理工具使用。
2、可以集中管理配置文件。
3.3.2 Zookeeper的安装
1 | 安装环境: |
3.4 工程改造:
3.4.1 拆分工程(之前我们做过了,来回顾下)
1 | 1)将表现层工程独立出来: |
3.4.2 服务层工程
第一步:把e3-manager的pom文件中删除e3-manager-web模块。
第二步:把e3-manager-web文件夹移动到e3-manager同一级目录。
第三步:e3-manager-service的pom文件修改打包方式
第四步:在e3-manager-service工程中添加web.xml文件
第五步:把e3-manager-web的配置文件复制到e3-manager-service中。
删除springmvc.xml
第六步:web.xml 中只配置spring容器。删除前端控制器
第七步:发布服务
- 在e3-manager-Service工程中添加dubbo依赖的jar包
1 | <?xml version="1.0" encoding="UTF-8"?> |
注意spring排除
- 在spring的配置文件中添加dubbo的约束,然后使用dubbo:service发布服务。
3.4.3 表现层工程
改造e3-manager-web工程。
第一步:删除mybatis、和spring的配置文件。只保留springmvc.xml
第二步:修改e3-manager-web的pom文件,
1、修改parent为e3-parent
2、添加spring和springmvc的jar包的依赖
3、删除e3-mangager-service的依赖
4、添加dubbo的依赖
1 | <!-- dubbo相关 --> |
5、e3-mangager-web添加对e3-manager-Interface的依赖。
第三步:修改springmvc.xml,在springmvc的配置文件中添加服务的引用。
1 | <!-- 引用dubbo服务 --> |
第四步:在e3-manager-web工程中添加tomcat插件配置。
1 | <build> |
注意:我们在测试这个服务的时候,需要将对象实现序列化接口,你想啊,咱们是在网络中传输的(我之前说过),并且需要在虚拟机上开启zookeeper服务,不然你查不到的,就像后面我在搭建监控中心的时候,没有开启zookeeper就在那查,结果卡了一个多小时
3.5 Dubbo监控中心:
先将dubbo-admin-2.5.4.war上传到Linux服务器上去,并部署到tomcat得而webapps中1
2
3
4
5
6
7
81、部署监控中心:
[root@localhost ~]# cp dubbo-admin-2.5.4.war apache-tomcat-7.0.47/webapps/dubbo-admin.war
2、启动tomcat
3、访问http://192.168.25.167:8080/dubbo-admin/
用户名:root
密码:root
以上是成功后的场景,不容易啊,卡了一个多小时呢,你在开启tomcat之前,必须先得把zookeeper服务打开,不然跑不起来
四.商品列表查询
4.1 导入后台页面:
4.2 书写Controller:
1 | /** |
注意:@RequestMapping(“/“),因为我们现在是先显示商城的首页,所以使用”/“,注意还需要删除掉原来自带的index.jsp
访问:http://localhost:8082/
效果如下:
我们的样式呢?
傻子,我们现在用的是springmvc,在web.xml里面的前端控制器中我们配置的url-pattern是 / 所以它拦截了jsp,js,css(你可以看看之前的笔记),那怎么办呢?
这个时候我们需要在springmvc中配置一个资源映射,专门来映射静态资源的
1 | <!--配置资源映射--> |
4.3 分页插件PageHelper:
4.3.1 Mybatis分页插件 - PageHelper说明
如果你也在用Mybatis,建议尝试该分页插件,这个一定是最方便使用的分页插件。
该插件目前支持Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库分页。
4.3.2 使用方法
第一步:把PageHelper依赖的jar包添加到工程中。官方提供的代码对逆向工程支持的不好,使用参考资料中的pagehelper-fix。
第二步:在Mybatis配置xml中配置拦截器插件:
1 | <plugins> |
第三步:在代码中使用
1、设置分页信息:
1 | //获取第1页,10条内容,默认查询总数count |
2、取分页信息
1 | //分页后,实际返回的结果list类型是Page<E>,如果想取出分页信息,需要强制转换为Page<E>, |
3、取分页信息的第二种方法
1 | //获取第1页,10条内容,默认查询总数count |
4.3.3 分页测试:
1 | public class PageHelperTest { |
4.4 EasyUI功能分析:
4.4.1 商品列表页面:
对应的jsp为:
item-list.jsp
请求的url:
/item/list
请求的参数:
page=1&rows=30
响应的json数据格式:
==Easyui中datagrid控件要求的数据格式为:==
=={total:”2”,rows:[{“id”:”1”,”name”:”张三”},{“id”:”2”,”name”:”李四”}]}==
4.4.2 响应的json数据格式EasyUIResult:
1 | public class EasyUIDataGridResult { |
4.5 代码编写:
4.5.1 Controller:
1 | @Controller |
看第二个方法EasyUIDataGridResult
4.5.2 Interface:
1 | public interface ItemService { |
看第二个方法EasyUIDataGridResult
4.5.3 Service:
1 | @Service |
看第二个方法getItemList
Dao不需要,我们用的是Mybatis的分页插件