在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:go-yea开源软件地址:https://gitee.com/yiyongfei/go-yea开源软件介绍:go-yeaYEA使用go-yea前,请先下载yea,并且执行yea/pom.xml mvn clean install -Dmaven.test.skip=true 概述YEA是什么GO-YEA是YEA的一个应用,它是一个极其容易使用的分布式框架,致力于提供产品的快速启动以及后续的服务伸缩。其核心部分包含:
YEA能做什么首先它是一个分布式服务框架,通过高性能的RPC远程调用以及SOA服务治理,提升产品在各个阶段不同的可伸缩要求。以达到最大程度降低由于伸缩性的改变对整个项目的变动影响。系统伸缩性通常以三种方式完成:1、增加副本;2、功能分割;3、数据分割。YEA主要考虑前二种方式。
通过go-yea-launcher里配置的DefaultClient,以支持同JVM间Act相互调用 <bean id="launcherClient" class="com.yea.core.remote.client.DefaultClient" /> 在go-yea-web里建立与go-yea-launcher的依赖关系,且将go-yea-launcher里的配置文件引入 <import resource="classpath:/application-launcher.xml" />
go-yea-launcher作为服务生产者对外提供服务。 <bean id="nettyServer" class="com.yea.remote.netty.server.NettyServer" /> go-yea-web作为服务消费者通过NettyClient远程调用服务生产者所提供的服务来完成业务操作(不依赖于go-yea-launcher) <bean id="nettyClient" class="com.yea.remote.netty.client.NettyClient" />
基于产品线规划将go-yea-launcher拆分成go-yea-launcher-permission与go-yea-launcher-authorization,以二个不同的注册名向Zookeeper注册。 go-yea-web将建立二个Netty客户端分别与go-yea-launcher-permission与go-yea-launcher-authorization建立连接。 其次它是一个快速启动的应用开发平台,集成了项目中常用的基础组件。
附上性能测试数据。测试环境:三台Vultr的云主机,各1 CPU(单核),1024MB 内存,一台部署go-yea-web(Tomcat),一台部署Launcher(启三个服务,每个服务占用堆内存128MB),一台部署Jmeter用于测试。测试软件:Jmeter。测试说明:调用api:permission/operation/query。执行路径Jmeter--(http)-->Go-yea-web--(netty)-->Launcher--(tcp)-->DB--(tcp)-->Launcher--(netty)-->Go-yea-web--(http)-->Jmeter测试结果(360并发):详细数据:详细结果提升性能指标:可以考虑先适当增加CPU核数和内存容量,然后再横向扩充。纵向扩展对比:测试环境:二台Vultr的云主机,各2 CPU,4096MB 内存测试说明:调用api:permission/operation/query。执行路径Jmeter--(http)-->Go-yea-web--(netty)-->Launcher--(tcp)-->DB--(tcp)-->Launcher--(netty)-->Go-yea-web--(http)-->Jmeter测试结果(999并发):详细数据:详细结果 访问GO-YEA(部署在bluemix上)
启动单机模式1、准备数据库
2、Maven打包执行go-yea/pom.xml: mvn clean package -Dmaven.test.skip=true -Pdevelop 3、部署Web服务复制go-yea-web/target/go-yea-web.war到应用服务器部署目录内,启动服务器 4、登录访问
RPC模式1、准备数据库参见单机模式 2、安装zookeeper3、Maven打包执行go-yea/pom.xml: mvn clean package -Dmaven.test.skip=true 4、启动APP服务复制go-yea/go-yea-launcher/target/go-yea-launcher-0.0.1-release.tar.gz到执行目录 tar -xzvf go-yea-launcher-0.0.1-release.tar.gz;cd launcher;sh start.sh; 启动时会要求输入Netty服务端绑定端口,输入端口或直接回车 5、部署Web服务复制go-yea-web/target/go-yea-web.war到应用服务器部署目录内,启动服务器 6、登录访问
注意RPC模式下,启动Web服务时会调用APP服务初始化Shiro权限管理信息,启动顺序先APP后WEB。实际应用中可单独部署一台APP用于提供统一认证授权服务。 开发APP服务向外部系统提供APP服务接口,服务内部实现具体的业务场景。可参照go-yea的结构建立Maven项目结构:
1、建立通用Dao类@Repositorypublic class CommonDao<T> extends AbstractBaseDAO<T> { 省略}
2、建立Model层
3、建立模块对应的Maven Module Project
4、建立启动器
<!-- JVM内调用,注意,DefaultClient需设置lazy为false,以确保向ClientRegister注册本地客户端 --> <bean id="launcherClient" class="com.yea.core.remote.client.DefaultClient" lazy-init="false" init-method="connect" destroy-method="disconnect" ></bean>
<!-- JVM内调用,注意,DefaultClient需设置lazy为false,以确保向ClientRegister注册本地客户端 --> <bean id="launcherClient" class="com.yea.core.remote.client.DefaultClient" lazy-init="false" init-method="connect" destroy-method="disconnect" ></bean> <!-- Netty编解码的Handler实现 --> <!-- 编码Handle的构造参数,可以设定序列化时将使用压缩算法压缩数据 --> <bean id="nettyMessageEncoder" class="com.yea.remote.netty.codec.NettyMessageEncoder"> <constructor-arg value="DEFLATE"/> </bean> <bean id="nettyMessageDecoder" class="com.yea.remote.netty.codec.NettyMessageDecoder"></bean> <!-- Netty心跳检测Handler实现 --> <bean id="heartBeatServerHandler" class="com.yea.remote.netty.server.handle.HeartBeatServerHandler"> <constructor-arg index="0" type="int" value="60"/> <constructor-arg index="1" type="int" value="60"/> </bean> <!-- Ping,用于负载均衡Ping类(检测服务连通性) --> <bean id="pingHandler" class="com.yea.remote.netty.handle.PingHandler"></bean> <!-- Netty服务处理Handler实现,所有业务操作均由该Handler处理 --> <bean id="serviceServerHandler" class="com.yea.remote.netty.server.handle.ServiceServerHandler"></bean> <!-- Netty异常处理Handler实现,Netty处理时若抛出异常,由该Handler封装异常并返回调用端 --> <bean id="exceptionHandler" class="com.yea.remote.netty.handle.ExceptionHandler"></bean> <!-- Zookeeper调度中心的配置 --> <bean id="zkDispatcher" class="com.yea.dispatcher.zookeeper.ZookeeperDispatcher" init-method="init"> <property name="host" value="${zookeeper.host}" /> <property name="port" value="${zookeeper.port}" /> </bean> <!-- Netty服务端配置,Netty服务启动将在Main内调用(外部提供服务绑定端口),启动服务后向调度中心发送服务注册请求 --> <bean id="nettyServer" class="com.yea.remote.netty.server.NettyServer" destroy-method="shutdown"> <property name="registerName" value="${netty.server.register}" /><!-- 服务注册名,将在Zookeeper内注册 --> <property name="dispatcher" ref="zkDispatcher" /> <property name="host" value="${netty.server.host}" /><!-- 该主机未设置时,系统将会读取本机IP自动设入 --> <property name="port" value="${netty.server.port}" /><!-- 该端口在执行start.sh脚本时,允许外部输入并替换 --> <property name="listHandler"> <list> <map> <entry key="MessageDecoder"> <ref bean="nettyMessageDecoder"/> </entry> </map> <map> <entry key="MessageEncoder"> <ref bean="nettyMessageEncoder"/> </entry> </map> <map> <entry key="HeartBeatHandler"> <ref bean="heartBeatServerHandler"/> </entry> </map> <map> <entry key="PingHandler"> <ref bean="pingHandler"/> </entry> </map> <map> <entry key="ServiceHandler"> <ref bean="serviceServerHandler"/> </entry> </map> <map> <entry key="ExceptionHandler"> <ref bean="exceptionHandler"/> </entry> </map> </list> </property> </bean> <!-- Netty服务端的配置 End -->
5、生成Mybatis的映射文件及相应的Domain进入开发管理->生成工具
6、Repository以及Service7、Act(重点)APP服务对外暴露的接口,客户端请求服务端时需提供Act名,Netty服务端收到请求后根据Act名找到相应的Bean并执行
@Servicepublic class QueryOperationAct extends AbstractAct { protected Object perform(Object[] messages) throws Throwable { 省略 }}
@Servicepublic class SaveOperationAct extends AbstractTransactionAct { protected Object perform(Object[] messages) throws Throwable { 省略 }} WEB服务提供Web服务,主要完成参数封装、页面展示。可参照go-yea的结构建立Maven项目结构:
1、pom.xml
<profile> <!-- 单机模式 --> <id>standalone</id> <properties> <profiles.active>standalone</profiles.active> </properties> <dependencies> <dependency> <groupId>com.team</groupId> <artifactId>go-yea-launcher</artifactId> <version>0.0.1</version> </dependency> </dependencies></profile>
<profile> <!-- RPC模式 --> <id>rpc</id> <properties> <profiles.active>rpc</profiles.active> </properties> <dependencies> <dependency> <groupId>com.yea</groupId> <artifactId>yea-dispatcher</artifactId> </dependency> </dependencies></profile> 2、spring-bean.xml
<import resource="classpath:/application-launcher.xml" />
<!-- Netty编解码的Handler实现 --> <bean id="nettyMessageEncoder" class="com.yea.remote.netty.codec.NettyMessageEncoder"> <constructor-arg value="DEFLATE"/> </bean> <bean id="nettyMessageDecoder" class="com.yea.remote.netty.codec.NettyMessageDecoder"></bean> <!-- Netty异常处理Handler实现,Netty处理时若抛出异常,由该Handler封装异常并返回调用端 --> <bean id="exceptionHandler" class="com.yea.remote.netty.handle.ExceptionHandler"></bean> <!-- Netty心跳检测Handler实现 --> <bean id="heartBeatClientHandler" class="com.yea.remote.netty.client.handle.HeartBeatClientHandler"> <constructor-arg index="0" type="int" value="60"/> <constructor-arg index="1" type="int" value="60"/> </bean> <bean id="pingHandler" class="com.yea.remote.netty.handle.PingHandler"></bean> <!-- Netty客户端收到服务端响应后的处理Handler实现 --> <bean id="serviceClientHandler" class="com.yea.remote.netty.client.handle.ServiceClientHandler"></bean> <!-- Netty服务处理Handler实现,所有业务操作均由该Handler处理,配置该Handle是为了支持双向调用,由服务端主动发起请求,如果发送的动作均由客户端发起,该Handle可以不配置在客户端内 --> <bean id="serviceServerHandler" class="com.yea.remote.netty.server.handle.ServiceServerHandler"></bean> <!-- 调度中心的配置 --> <bean id="zkDispatcher" class="com.yea.dispatcher.zookeeper.ZookeeperDispatcher" init-method="init"> <property name="host" value="${zookeeper.host}" /> <property name="port" value="${zookeeper.port}" /> </bean> <!-- Netty客户端配置,启动时将会根据服务注册名主动连接服务端 --> <bean id="nettyClient" class="com.yea.remote.netty.client.NettyClient" init-method="connect" destroy-method="disconnect"> <property name="registerName" value="${netty.server.register}" /><!-- 服务注册名 --> <property name="dispatcher" ref="zkDispatcher" /> <property name="host" value="${netty.client.host}" /><!-- 该主机未设置时,系统将会读取本机IP自动设入 --> <property name="port" value="${netty.client.port}" /><!-- 该端口在执行start.sh脚本时,允许外部输入并替换 --> <property name="listHandler"> <list> <map> <entry key="MessageDecoder"> <ref bean="nettyMessageDecoder"/> </entry> </map> <map> <entry key="MessageEncoder"> <ref bean="nettyMessageEncoder"/> </entry> </map> <map> <entry key="HeartBeatHandler"> <ref bean="heartBeatClientHandler"/> </entry> </map> <map> <entry key="PingHandler"> <ref bean="pingHandler"/> </entry> </map> <map> <entry key="ServiceClientHandler"> <ref bean="serviceClientHandler"/> </entry> </map> <map> <entry key="ServiceServerHandler"> <ref bean="serviceServerHandler"/> </entry> </map> <map> <entry key="ExceptionHandler"> <ref bean="exceptionHandler"/> </entry> </map> </list> </property> </bean>
<bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator"/> <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"> <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/> <property name="sessionIdGenerator" ref="sessionIdGenerator"/> </bean> <!-- 会话Cookie模板 --> <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg value="JEA_SESSIONID"/> <property name="httpOnly" value="true"/> <property name="maxAge" value="-1"/> <!-- maxAge=-1,表示浏览器关闭时失效此Cookie --> </bean> <!-- 会话管理器 --> <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> <property name="globalSessionTimeout" value="1800000"/> <property name="deleteInvalidSessions" value="true"/> <property name="sessionValidationSchedulerEnabled" value="true"/> <property name="sessionDAO" ref="sessionDAO"/> <property name="sessionIdCookieEnabled" value="true"/> <property name="sessionIdCookie" ref="sessionIdCookie"/> </bean> <!-- rememberMe的Cookie模板 --> <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> <constructor-arg value="rememberMe"/> <property name="httpOnly" value="true"/> <property name="maxAge" value="604800"/><!-- 记住我的Cookie,保存时长7天 --> </bean> <!-- rememberMe管理器 --> <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"> <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('9AVvhnFLuS3KTV8KprsdAg==')}" /> <property name="cookie" ref="rememberMeCookie"/> </bean> <bean id="securityManager" class="com.yea.shiro.web.mgt.WebSecurityManager"> <property name="endpoint" ref="nettyClient"/> <property name="sessionManager" ref="sessionManager"/> <property name="rememberMeManager" ref="rememberMeManager"/> </bean> <!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) --> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"/> <property name="arguments" ref="securityManager"/> </bean> <!-- Shiro的Web过滤器 --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" > <property name="securityManager" ref="securityManager"/> <property name="loginUrl" value="/login.html"/> <property name="successUrl" value="/index.html"/> <property name="unauthorizedUrl" value="/unauthorized.html"/> </bean> <!-- 对ShiroWeb过滤器进行包装,以初始化过滤器链(不允许延迟加载) --> <bean id="shiroFilterWrapper" class="com.yea.shiro.web.wrapper.ShiroFilterWrapper" init-method="init" lazy-init="false" > <property name="endpoint" ref="nettyClient"/> <property name="shiroFilter" ref="shiroFilter"/> <property name="authenticedUrl" value="/authenticed.html"/> <property name="logoutUrl" value="/logout.html"/> </bean> <!-- Shiro生命周期处理器--> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
<!-- Redis池 --> <bean id="redisGeneralPool" class="com.yea.cache.jedis.pool.RedisGeneralPool" init-method="initPool" destroy-method="destroyPool"> <property name="server" value="${redis.server}"/> </bean> <!-- RedisSessionDAO的支持,将Session放置在Redis服务上,可解决多Web服务器的Session同步问题 --> <bean id="sessionDAO" class="com.yea.shiro.session.mgt.redis.ShiroSessionDAO"> <property name="cachePool" ref="redisGeneralPool"/> </bean> 3、spring-mvc.xml
|
请发表评论