webservice :系统之间通信。应用于外部系统,并且数据交换不是特别大的情况下(传统行业 OA 与ERP之间的通信)
http+json: 系统之间通信 。属于http的协议,restful风格传递数据,(手机客户端和后台进行通信 SSO系统给手机发布接口调用,传递JSON)
dubbo:系统之间的通信. 属于RPC的协议(底层二进制协议),使用socket 通信,传输效率高,一般用于内部系统之间。作为SOA架构的管理工具,能统计各个服务调用的次数。
系统架构
1. 传统架构
1.1. 500并发
图5.1
存在的问题:
1、功能耦合度高
2、系统维护成本高
3、如果并发量大,无法解决高并发的问题
1.2. 1000并发
存在的问题:
1、系统无法有效进行水平扩展(集群不能针对功能模块)图5.1
2、用户存在重复登录的问题
针对第二点:需要session共享,是以session广播的形式,比较消耗资源,宽带。
(1)通过数据库mysql共享session
a.采用一台专门的mysql服务器来存储所有的session信息。
用户访问随机的web服务器时,会去这个专门的数据库服务器check一下session的情况,以达到session同步的目的。
缺点就是:依懒性太强,mysql服务器无法工作,影响整个系统;
b.将存放session的数据表与业务的数据表放在同一个库。如果mysql做了主从,需要每一个库都需要存在这个表,并且需要数据实时同步。
缺点:用数据库来同步session,会加大数据库的负担,数据库本来就是容易产生瓶颈的地方,如果把session还放到数据库里面,无疑是雪上加霜。上面的二种方法,第一点方法较好,把放session的表独立开来,减轻了真正数据库的负担 。但是session一般的查询频率较高,放在数据库中查询性能也不是很好,不推荐使用这种方式。
(2)通过cookie共享session
把用户访问页面产生的session放到cookie里面,就是以cookie为中转站。
当访问服务器A时,登录成功之后将产生的session信息存放在cookie中;当访问请求分配到服务器B时,服务器B先判断服务器有没有这个session,如果没有,在去看看客户端的cookie里面有没有这个session,如果cookie里面有,就把cookie里面的sessoin同步到web服务器B,这样就可以实现session的同步了。
缺点:cookie的安全性不高,容易伪造、客户端禁止使用cookie等都可能造成无法共享session。
(3)通过服务器之间的数据同步session
使用一台作为用户的登录服务器,当用户登录成功之后,会将session写到当前服务器上,我们通过脚本或者守护进程将session同步到其他服务器上,这时当用户跳转到其他服务器,session一致,也就不用再次登录。
缺陷:速度慢,同步session有延迟性,可能导致跳转服务器之后,session未同步。而且单向同步时,登录服务器宕机,整个系统都不能正常运行。
(4)通过NFS共享Session
选择一台公共的NFS服务器(Network File Server)做共享服务器,所有的Web服务器登陆的时候把session数据写到这台服务器上,那么所有的session数据其实都是保存在这台NFS服务器上的,不论用户访问那太Web服务器,都要来这台服务器获取session数据,那么就能够实现共享session数据了。
缺点:依赖性太强,如果NFS服务器down掉了,那么大家都无法工作了,当然,可以考虑多台NFS服务器同步的形式。
(5)通过memcache同步session
memcache可以做分布式,如果没有这功能,他也不能用来做session同步。他可以把web服务器中的内存组合起来,成为一个"内存池",不管是哪个服务器产生的sessoin都可以放到这个"内存池"中,其他的都可以使用。
优点:以这种方式来同步session,不会加大数据库的负担,并且安全性比用cookie大大的提高,把session放到内存里面,比从文件中读取要快很多。
缺点:memcache把内存分成很多种规格的存储块,有块就有大小,这种方式也就决定了,memcache不能完全利用内存,会产生内存碎片,如果存储块不足,还会产生内存溢出。
(6)通过redis共享session
redis与memcache一样,都是将数据放在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
根据实际开发应用,一般选择使用memcache或redis方式来共享session.
如果要达到10000并发
需要20台服务器做tomcat集群。当tomcat集群中节点数量增加,服务能力先增加后下降。
所以集群中节点数量不能太多,一般也就5个左右。
2. 分布式架构(10000并发)
需要按照功能点把系统拆分,拆分成独立的功能工程,可以单独为某一个节点添加服务器,需要系统之间配合才能完成整个业务逻辑这就叫做分布式。
集群:相当于同一个工程代码拷贝多份部署到多台服务器,每台服务器单独独立部署运行。
分布式架构:
把系统按照模块拆分成多个子系统;多个子系统相互协作才能完成业务流程系统之间需要进行通信。
优点:
1、把模块拆分,使用接口通信,降低模块之间的耦合度。
2、把项目拆分成若干个子项目,不同的团队负责不同的子项目。
3、增加功能时只需要再增加一个子项目,调用其他系统的接口就可以。
4、可以灵活的进行分布式部署。
缺点:
1、系统之间交互需要使用远程通信,需要开发接口,增加工作量。
2、各个模块有一些通用的业务逻辑无法公用。
5.2.1. 基于SOA的架构
SOA:Service Oriented Architecture面向服务的架构。也就是把工程都拆分成服务层工程、表现层工程。服务层中包含业务逻辑,只需要对外提供服务即可。表现层只需要处理和页面的交互,业务逻辑都是调用服务层的服务来实现。工程都可以独立部署。
Dobbox
Dobbox两个注解@ Service 用于service类的定义 和 @Reference 用于web层的引入service。 设置连接时间@Service(timeout=5000)
1.Dobbox简介:
Dubbox 是一个分布式服务框架, 使用RPC( Remote Procedure Call)远程过程调用方案。
2.原理图:
节点角色说明:
Registry: 服务注册中心。
Provider: 服务提供者。
Container: 服务提供者运行的容器。
Consumer: 调用远程服务的消费者。
Monitor: 统计服务的调用次调和调用时间的监控中心。
运行顺序:
0. 服务容器负责启动,加载,运行服务提供者。
1. 服务提供者在启动时,向注册中心注册自己提供的服务。
2. 服务消费者在启动时,向注册中心订阅自己所需的服务。
3. 注册中心返回服务提供者地址列表给消费者。如果有变更,注册中心将基于长连接推送变更数据给消费者。
4. 服务消费者从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用。如果调用失败,再选另一台调用。
5. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
连接dubbox注册中心的端口默认是20880,每个启动的服务端口端口应该改变。
Zookeeper注册中心
1. Zookeeper 注册中心介绍:
官方推荐使用 zookeeper 注册中心。注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小。
2.Zookeeper单个服务配置
上传至系统
解压文件 tart zxvf zookeeper-3.4.6.tar.gz
把zookeeper上传到系统,创建一个data文件夹,用来存储数据 mkdir data
修改配置文件名 mv zoo_samplie.cfg zoo.cfg
修改文件内容 vim zoo.cfg
按i进入插入模式
修改 dataDir文件为上面的文件 或者修改端口(看情况是否修改)-------复制剪贴板内容到命令行,复制文成后鼠标右键就可以复制过来
esc退出插入模式
:mq 保存退出
:q 不保存退出
3..Zookeeper启动
bean目录---》 ./zkServer.sh start
查看linux服务的ip config
dobbox+zookeeper+SSM
service层的配置
1.添加依赖
<!-- 上面添加Spring相关的 -->
<!-- dubbo相关 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.11.0.GA</version>
</dependency>
注意添加端口
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<!-- 指定端口 -->
<port>9001</port>
<!-- 请求路径 -->
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
2.web.xml配置
<!-- 加载spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
3.applicationContext-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:p="http://www.springframework.org/schema/p"
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:protocol name="dubbo" port="20881"></dubbo:protocol>
<dubbo:application name="pinyougou-sellergoods-service"/>
<dubbo:registry address="zookeeper://192.168.25.130:2181"/>
<dubbo:annotation package="com.pinyougou.sellergoods.service.impl" />
<!--本身就带spring的包扫描-->
</beans>
4.注意 服务的提供方注解使用的dobbox的@service注解
web层的配置
1.添加依赖----------service层的依赖一样,注意添加的端口不一样
2.web.xml相关配置
<!-- 解决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:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
3.spring-mvc.xml的配置
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="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: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>
<mvc:message-convertersregister-defaults="true">
<beanclass="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<propertyname="supportedMediaTypes"value="application/json"/>
<propertyname="features">
<array>
<value>WriteMapNullValue</value>
<value>WriteDateUseDateFormat</value>
</array>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 引用dubbo 服务 -->
<dubbo:application name="pinyougou-manager-web"/>
<dubbo:registry address="zookeeper://192.168.25.132:2181"/>
<dubbo:annotation package="com.pinyougou.manager.controller"/>
</beans>
4..服务的消费方注意事项
引用service实现类用dobbo的@Reference注解
@Reference
private UserService userService;
附录:常见错误
1.在注册中心找不到对应的服务
java.lang.IllegalStateException: Failed to check the status of the service com.pinyougou.sellergoods.service.BrandService. No provider available for the service com.pinyougou.sellergoods.service.BrandService from the url zookeeper://192.168.25.129:2181/com.alibaba.dubbo.registry.RegistryService?application=pinyougou-manager-web&dubbo=2.8.4&interface=com.pinyougou.sellergoods.service.BrandService&methods=update,get,delete,selectOptionList,add,getListByPage&pid=3980&revision=0.0.1-SNAPSHOT&side=consumer×tamp=1501146823396 to the consumer 172.16.17.14 use dubbo version 2.8.4 |
这种错误是服务层代码没有成功注册到注册中心导致,请检查一下你的服务层代码是否添加了@service注解,并且该注解的包一定是com.alibaba.dubbo.config.annotation包,不是org.springframework.stereotype.Service,这个地方极容易出错。另外还有一个原因就是你的服务层工程由于某些原因没有正常启动,也无法注册到注册中心里。
2.无法连接到注册中心
org.I0Itec.zkclient.exception.ZkTimeoutException: Unable to connect to zookeeper server within timeout: 5000 org.I0Itec.zkclient.ZkClient.connect(ZkClient.java:876) org.I0Itec.zkclient.ZkClient.<init>(ZkClient.java:98) org.I0Itec.zkclient.ZkClient.<init>(ZkClient.java:92) org.I0Itec.zkclient.ZkClient.<init>(ZkClient.java:80) com.alibaba.dubbo.remoting.zookeeper.zkclient.ZkclientZookeeperClient.<init>(ZkclientZookeeperClient.java:26) |
请检查IP与端口是否填写正确,检查注册中心是否正常启动
-
实体类没有实现序列化
实体类没有实现序列化