├── .gitignore ├── README.md ├── pom.xml ├── xultimate-remoting-burlap ├── pom.xml ├── result.txt └── src │ └── main │ ├── java │ └── org │ │ └── danielli │ │ └── xultimate │ │ └── remoting │ │ └── web │ │ └── controller │ │ └── AccountController.java │ ├── resources │ ├── applicationContext-service-remoting-burlap.xml │ └── applicationContext-servlet.xml │ └── webapp │ └── WEB-INF │ ├── templates │ ├── account_add.httl │ └── account_list.httl │ └── web.xml ├── xultimate-remoting-cxf ├── pom.xml ├── result.txt └── src │ └── main │ ├── java │ └── org │ │ └── danielli │ │ └── xultimate │ │ └── remoting │ │ ├── service │ │ ├── AccountServiceEndpoint.java │ │ └── cxf │ │ │ └── AccountServiceEndpointImpl.java │ │ └── web │ │ └── controller │ │ └── AccountController.java │ ├── resources │ ├── applicationContext-service-remoting-cxf.xml │ └── applicationContext-servlet.xml │ └── webapp │ └── WEB-INF │ ├── templates │ ├── account_add.httl │ └── account_list.httl │ └── web.xml ├── xultimate-remoting-dubbo ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── danielli │ │ │ └── xultimate │ │ │ ├── remoting │ │ │ ├── dubbo │ │ │ │ ├── container │ │ │ │ │ ├── Main.java │ │ │ │ │ └── spring │ │ │ │ │ │ └── SpringContainer.java │ │ │ │ └── serialize │ │ │ │ │ └── support │ │ │ │ │ ├── ObjectInput.java │ │ │ │ │ ├── ObjectOutput.java │ │ │ │ │ ├── java │ │ │ │ │ └── JavaSerialization.java │ │ │ │ │ ├── kryo │ │ │ │ │ └── KryoSerialization.java │ │ │ │ │ ├── protobuf │ │ │ │ │ └── ProtobufSerialization.java │ │ │ │ │ └── protostuff │ │ │ │ │ └── ProtostuffSerialization.java │ │ │ └── web │ │ │ │ └── controller │ │ │ │ └── AccountController.java │ │ │ └── zookeeper │ │ │ ├── CuratorFrameworkFactoryBean.java │ │ │ └── SetACLCommandExecutor.java │ ├── resources │ │ ├── META-INF │ │ │ └── dubbo │ │ │ │ ├── com.alibaba.dubbo.common.serialize.Serialization │ │ │ │ └── com.alibaba.dubbo.container.Container │ │ ├── applicationContext-service-remoting-dubbo-client.xml │ │ ├── applicationContext-service-remoting-dubbo-server.xml │ │ ├── applicationContext-servlet.xml │ │ └── dubbo.properties │ └── webapp │ │ └── WEB-INF │ │ ├── templates │ │ ├── account_add.httl │ │ └── account_list.httl │ │ └── web.xml │ └── test │ └── java │ └── org │ └── danielli │ └── xultimate │ └── remoting │ └── dubbo │ └── serialize │ ├── Consumer.java │ └── SerializationTest.java ├── xultimate-remoting-hessian ├── pom.xml ├── result.txt └── src │ └── main │ ├── java │ └── org │ │ └── danielli │ │ └── xultimate │ │ └── remoting │ │ └── web │ │ └── controller │ │ └── AccountController.java │ ├── resources │ ├── applicationContext-service-remoting-hessian.xml │ └── applicationContext-servlet.xml │ └── webapp │ └── WEB-INF │ ├── templates │ ├── account_add.httl │ └── account_list.httl │ └── web.xml ├── xultimate-remoting-httpinvoker ├── pom.xml ├── result.txt └── src │ └── main │ ├── java │ └── org │ │ └── danielli │ │ └── xultimate │ │ └── remoting │ │ └── web │ │ └── controller │ │ └── AccountController.java │ ├── resources │ ├── applicationContext-service-remoting-httpinvoker.xml │ └── applicationContext-servlet.xml │ └── webapp │ └── WEB-INF │ ├── templates │ ├── account_add.httl │ └── account_list.httl │ └── web.xml ├── xultimate-remoting-jms ├── pom.xml └── src │ └── main │ ├── java │ └── org │ │ └── danielli │ │ └── xultimate │ │ └── remoting │ │ ├── service │ │ ├── CheckingAccountService.java │ │ └── impl │ │ │ └── SimpleCheckingAccountService.java │ │ └── web │ │ └── controller │ │ └── AccountController.java │ ├── resources │ ├── applicationContext-service-remoting-jms-client.xml │ ├── applicationContext-service-remoting-jms-server.xml │ ├── applicationContext-service-remoting-jms-share.xml │ └── applicationContext-servlet.xml │ └── webapp │ └── WEB-INF │ ├── templates │ └── account_cancel_success.httl │ └── web.xml ├── xultimate-remoting-metaq ├── pom.xml └── src │ └── main │ ├── java │ └── org │ │ └── danielli │ │ └── xultimate │ │ └── remoting │ │ ├── dto │ │ └── Logging.java │ │ ├── metaq │ │ ├── MessageProducerCallback.java │ │ ├── MessageProducerWithMessageCallback.java │ │ ├── MetaqClientException.java │ │ ├── MetaqTemplateUtils.java │ │ └── support │ │ │ ├── JavaObjectConverter.java │ │ │ ├── MetaqTemplate.java │ │ │ ├── RpcKryoObjectConverter.java │ │ │ ├── RpcProtobufObjectConverter.java │ │ │ ├── RpcProtostuffObjectConverter.java │ │ │ └── XMemcachedMessageIdCache.java │ │ ├── service │ │ ├── LoggingService.java │ │ └── impl │ │ │ ├── LoggingServiceImpl.java │ │ │ ├── MetaqClientLoggingService.java │ │ │ └── MetaqLoggingMessageListener.java │ │ └── web │ │ └── controller │ │ └── LoggingController.java │ ├── resources │ ├── applicationContext-service-memcached.xml │ ├── applicationContext-service-remoting-metaq-client.xml │ ├── applicationContext-service-remoting-metaq-server.xml │ ├── applicationContext-servlet.xml │ └── meta_log4j.properties │ └── webapp │ └── WEB-INF │ ├── templates │ └── logging_save_success.httl │ └── web.xml ├── xultimate-remoting-rest ├── pom.xml ├── result.txt └── src │ └── main │ ├── java │ └── org │ │ └── danielli │ │ └── xultimate │ │ └── remoting │ │ ├── controller │ │ └── web │ │ │ ├── AccountController.java │ │ │ └── RemoteAccountController.java │ │ └── service │ │ └── impl │ │ └── RemoteAccountService.java │ ├── resources │ ├── applicationContext-service-remoting-rest.xml │ └── applicationContext-servlet.xml │ └── webapp │ └── WEB-INF │ ├── templates │ ├── account_add.httl │ └── account_list.httl │ └── web.xml ├── xultimate-remoting-rmi ├── pom.xml ├── result.txt └── src │ └── main │ ├── java │ └── org │ │ └── danielli │ │ └── xultimate │ │ └── remoting │ │ └── web │ │ └── controller │ │ └── AccountController.java │ ├── resources │ ├── applicationContext-service-remoting-rmi.xml │ └── applicationContext-servlet.xml │ └── webapp │ └── WEB-INF │ ├── templates │ ├── account_add.httl │ └── account_list.httl │ └── web.xml └── xultimate-remoting-service ├── pom.xml └── src └── main ├── java └── org │ └── danielli │ └── xultimate │ └── remoting │ ├── dto │ └── Account.java │ └── service │ ├── AccountService.java │ └── impl │ └── AccountServiceImpl.java └── resources └── applicationContext-service.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .settings 2 | .project 3 | .classpath 4 | 5 | *.class 6 | 7 | # Package Files # 8 | *.jar 9 | *.war 10 | *.ear 11 | 12 | target 13 | .springBeans -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # xultimate-remoting # 2 | 3 | * 起初只是提供Java中一些分布式远程调用的ShowCase,都是基于Spring来构建的,这样便于需要的时候提取并修改。 4 | * 基础的分布式调用包括RMI、HttpInvoker、Hessian、Burlap;异步调用提供ActiveMQ;Web服务则包括了REST、CXF。 5 | * 后来因为所参与的项目使用了RabbitMQ,而原有的封装经常会出现问题(过慢、CPU负载过高)导致应用崩溃,因此我重新封装了一套。客户端通过RabbitMQClientTemplate发送可序列化对象,序列化协议使用原有的Hessian协议,服务端搬照Tomcat的JIoEndpoint写法并采用信号量进行并发控制,中间通过JobService进行任务分配,最终通过定义不同的Job\完成具体任务。整个配置通过Spring定义。最终经过简单测试,发现性能有提升400倍左右。然后才开始真正关注和思考分布式调用。 6 | * 最终决定公共服务采用Spring MVC开发REST + JSON,同步调用采用Dubbo,异步调用采用MetaQ。 7 | 8 | 9 | ## xultimate-remoting-service ## 10 | 11 | * 包括了公共Service和Service实现类。 12 | 13 | 14 | ## xultimate-remoting-rmi ## 15 | 16 | * 提供了基于RMI协议的同步调用演示。 17 | 18 | 19 | ## xultimate-remoting-httpinvoker ## 20 | 21 | * 提供了基于Spring HTTP invoker的同步调用演示。 22 | 23 | 24 | ## xultimate-remoting-hessian ## 25 | 26 | * 提供了基于Hessian协议的同步调用演示。 27 | 28 | 29 | ## xultimate-remoting-burlap ## 30 | 31 | * 提供了基于Burlap协议的同步调用演示。 32 | 33 | 34 | ## xultimate-remoting-cxf ## 35 | 36 | * 提供了基于Apache CXF Web服务框架的调用演示。 37 | 38 | 39 | ## xultimate-remoting-rest ## 40 | 41 | * 提供了基于Spring MVC实现的REST风格,通过FastJSON实现JSON处理的调用演示。 42 | 43 | 44 | ## xultimate-remoting-jms ## 45 | 46 | * 提供了基于Apache ActiveMQ消息中间件的异步调用演示。 47 | 48 | 49 | ## xultimate-remoting-metaq ## 50 | 51 | * 提供了基于MetaQ队列模型消息中间件的异步调用演示。 52 | * 重写MetaqTemplate,功能是直接Copy过来的,只是觉得调用起来如何能更加方便。 53 | * 提供MessageProducerCallback和MessageProducerWithMessageCallback,用于回调处理。 54 | * 提供MetaqTemplateUtils,用于执行消息回调。 55 | * 提供RpcKryoObjectConverter、JavaObjectConverter,通过Kryo、Java默认的序列化/解序列化方式;同时具备压缩功能,可配置为GZIP、Snappy。 56 | * 提供RpcProtobufObjectConverter、RpcProtostuffObjectConverter,通过Protobuf、Protostuff的序列化/解序列化方式;同时具备压缩功能,可配置为GZIP、Snappy。 57 | * 提供XMemcachedMessageIdCache,消息ID实现,内部封装XMemcachedClient。 58 | 59 | 60 | ## xultimate-remoting-dubbo ## 61 | 62 | * 提供了基于Dubbo分布式服务框架的同步调用演示。 63 | * 提供ObjectInput、ObjectOutput,内部封装AbstractObjectInput、AbstractObjectOutput,提供真正解序列化。 64 | * 提供JavaSerialization,完成Java序列化/解序列化功能;同时具备压缩/解压缩功能,默认配置为Snappy;缓冲大小默认256;都可通过继承覆盖。 65 | * 提供KryoSerialization,完成Kryo序列化/解序列化功能;同时具备压缩/解压缩功能,默认配置为Snappy;缓冲大小默认256;都可通过继承覆盖。 66 | * 提供ProtobufSerialization,完成Protobuf序列化/解序列化功能;同时具备压缩/解压缩功能,默认配置为Snappy;缓冲大小默认256;都可通过继承覆盖。 67 | * 提供ProtostuffSerialization,完成Protostuff序列化/解序列化功能;同时具备压缩/解压缩功能,默认配置为Snappy;缓冲大小默认256;都可通过继承覆盖。 68 | * 提供CuratorFrameworkFactoryBean,用于通过Spring创建CuratorFramework实例。 69 | * 提供SetACLCommandExecutor,用于执行setACL指令。 70 | * 重写Main,强制使用dubbo.properties并声明dubbo.spring.config属性指定Spring配置文件。 -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.danielli.xultimate 7 | xultimate-remoting 8 | 1.0.0-SNAPSHOT 9 | pom 10 | 11 | The X-Ultimate Remoting Parent 12 | The X-Ultimate Remoting parent project. 13 | https://github.com/daniellitoc/xultimate-remoting/ 14 | 15 | 16 | 1.7 17 | 4.11 18 | 3.2.3.RELEASE 19 | 3.1.0 20 | 21 | 22 | 23 | 24 | ${project.groupId} 25 | xultimate-webmvc 26 | ${project.version} 27 | 28 | 29 | javax.servlet 30 | javax.servlet-api 31 | ${javax.servlet.javax.servlet-api.version} 32 | provided 33 | 34 | 35 | junit 36 | junit 37 | ${junit.version} 38 | test 39 | 40 | 41 | org.springframework 42 | spring-test 43 | ${org.springframework.version} 44 | test 45 | 46 | 47 | org.springframework 48 | spring-core 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | src/main/resources 58 | true 59 | 60 | 61 | 62 | 63 | src/test/resources 64 | true 65 | 66 | 67 | 68 | 69 | org.apache.maven.plugins 70 | maven-compiler-plugin 71 | 72 | ${jdk.version} 73 | ${jdk.version} 74 | 75 | 76 | 77 | org.apache.maven.plugins 78 | maven-resources-plugin 79 | 80 | UTF-8 81 | 82 | 83 | 84 | org.apache.maven.plugins 85 | maven-source-plugin 86 | 87 | 88 | attach-sources 89 | verify 90 | 91 | jar-no-fork 92 | 93 | 94 | 95 | 96 | 97 | org.apache.maven.plugins 98 | maven-javadoc-plugin 99 | 100 | 101 | attach-javadocs 102 | 103 | jar 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | nexus-releases 114 | Nexus Release Repository 115 | http://localhost/nexus/content/repositories/releases 116 | 117 | 118 | nexus-snapshots 119 | Nexus Snapshots Repository 120 | http://localhost/nexus/content/repositories/snapshots 121 | 122 | 123 | 124 | 125 | xultimate-remoting-service 126 | xultimate-remoting-rmi 127 | xultimate-remoting-rest 128 | xultimate-remoting-jms 129 | xultimate-remoting-httpinvoker 130 | xultimate-remoting-hessian 131 | xultimate-remoting-burlap 132 | xultimate-remoting-cxf 133 | xultimate-remoting-dubbo 134 | xultimate-remoting-metaq 135 | 136 | -------------------------------------------------------------------------------- /xultimate-remoting-burlap/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.danielli.xultimate 8 | xultimate-remoting 9 | 1.0.0-SNAPSHOT 10 | 11 | 12 | xultimate-remoting-burlap 13 | war 14 | 15 | The X-Ultimate Remoting Burlap 16 | The X-Ultimate Remoting burlap project. 17 | https://github.com/daniellitoc/xultimate-remoting/tree/master/xultimate-remoting-burlap 18 | 19 | 20 | 21 | com.caucho 22 | hessian 23 | 4.0.7 24 | 25 | 26 | ${project.groupId} 27 | xultimate-remoting-service 28 | ${project.version} 29 | 30 | 31 | 32 | 33 | xultimate-remoting-burlap 34 | 35 | 36 | -------------------------------------------------------------------------------- /xultimate-remoting-burlap/result.txt: -------------------------------------------------------------------------------- 1 | 测试过程中出现了异常。 2 | ab -c 100 -n 1000 http://127.0.0.1:8081/xultimate-remoting-burlap/accounts 3 | 4 | This is ApacheBench, Version 2.3 <$Revision: 655654 $> 5 | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 6 | Licensed to The Apache Software Foundation, http://www.apache.org/ 7 | 8 | Benchmarking 127.0.0.1 (be patient) 9 | Completed 100 requests 10 | Completed 200 requests 11 | Completed 300 requests 12 | Completed 400 requests 13 | Completed 500 requests 14 | Completed 600 requests 15 | Completed 700 requests 16 | Completed 800 requests 17 | Completed 900 requests 18 | Completed 1000 requests 19 | Finished 1000 requests 20 | 21 | 22 | Server Software: Apache-Coyote/1.1 23 | Server Hostname: 127.0.0.1 24 | Server Port: 8081 25 | 26 | Document Path: /xultimate-remoting-burlap/accounts 27 | Document Length: 776 bytes 28 | 29 | Concurrency Level: 100 30 | Time taken for tests: 0.290 seconds 31 | Complete requests: 1000 32 | Failed requests: 0 33 | Write errors: 0 34 | Total transferred: 962000 bytes 35 | HTML transferred: 776000 bytes 36 | Requests per second: 3444.14 [#/sec] (mean) 37 | Time per request: 29.035 [ms] (mean) 38 | Time per request: 0.290 [ms] (mean, across all concurrent requests) 39 | Transfer rate: 3235.61 [Kbytes/sec] received 40 | 41 | Connection Times (ms) 42 | min mean[+/-sd] median max 43 | Connect: 0 1 1.6 0 6 44 | Processing: 2 27 9.9 26 58 45 | Waiting: 1 26 8.9 26 50 46 | Total: 8 28 9.4 27 58 47 | 48 | Percentage of the requests served within a certain time (ms) 49 | 50% 27 50 | 66% 31 51 | 75% 34 52 | 80% 36 53 | 90% 41 54 | 95% 45 55 | 98% 50 56 | 99% 51 57 | 100% 58 (longest request) -------------------------------------------------------------------------------- /xultimate-remoting-burlap/src/main/java/org/danielli/xultimate/remoting/web/controller/AccountController.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.web.controller; 2 | 3 | import java.util.List; 4 | 5 | import javax.annotation.Resource; 6 | 7 | import org.danielli.xultimate.remoting.dto.Account; 8 | import org.danielli.xultimate.remoting.service.AccountService; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.ModelMap; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | 14 | @Controller 15 | @RequestMapping("/accounts") 16 | public class AccountController { 17 | 18 | @Resource(name = "remotingBurlapAccountService") 19 | public AccountService accountService; 20 | 21 | @RequestMapping(value = "/add", method = { RequestMethod.GET }) 22 | public String toInsertAccount() { 23 | return "account_add"; 24 | } 25 | 26 | @RequestMapping(method = { RequestMethod.POST }) 27 | public String doInsertAccount(Account account, ModelMap modelMap) { 28 | accountService.insertAccount(account); 29 | modelMap.put("name", account.getName()); 30 | return "redirect:/accounts"; 31 | } 32 | 33 | @RequestMapping(method = { RequestMethod.GET }) 34 | public String getAccounts(Account account, ModelMap modelMap) { 35 | List accountList = null; 36 | if (account == null || account.getName() == null) { 37 | accountList = accountService.getAllAccounts(); 38 | } else { 39 | accountList = accountService.getAccounts(account.getName()); 40 | } 41 | modelMap.put("accounts", accountList); 42 | return "account_list"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /xultimate-remoting-burlap/src/main/resources/applicationContext-service-remoting-burlap.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /xultimate-remoting-burlap/src/main/resources/applicationContext-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | import.packages+=org.danielli.xultimate.remoting.dto 38 | template.directory=/WEB-INF/templates/ 39 | input.encoding=UTF-8 40 | output.encoding=UTF-8 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /xultimate-remoting-burlap/src/main/webapp/WEB-INF/templates/account_add.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Add Account 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
18 |
19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-burlap/src/main/webapp/WEB-INF/templates/account_list.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Account List 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
${account.name}
18 | Add Account 19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-burlap/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | isLog4jAutoInitializationDisabled 5 | true 6 | 7 | 8 | 9 | org.apache.logging.log4j.web.Log4jServletContextListener 10 | 11 | 12 | 13 | log4jServletFilter 14 | org.apache.logging.log4j.web.Log4jServletFilter 15 | 16 | 17 | log4jServletFilter 18 | /* 19 | REQUEST 20 | FORWARD 21 | INCLUDE 22 | ERROR 23 | ASYNC 24 | 25 | 26 | 27 | contextConfigLocation 28 | classpath:applicationContext-service.xml, classpath:applicationContext-service-remoting-burlap.xml 29 | 30 | 31 | org.springframework.web.context.ContextLoaderListener 32 | 33 | 34 | 35 | spring 36 | org.springframework.web.servlet.DispatcherServlet 37 | 38 | contextConfigLocation 39 | classpath:applicationContext-servlet.xml 40 | 41 | 42 | 43 | spring 44 | / 45 | 46 | -------------------------------------------------------------------------------- /xultimate-remoting-cxf/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.danielli.xultimate 8 | xultimate-remoting 9 | 1.0.0-SNAPSHOT 10 | 11 | 12 | xultimate-remoting-cxf 13 | war 14 | 15 | The X-Ultimate Remoting CXF 16 | The X-Ultimate Remoting cxf project. 17 | https://github.com/daniellitoc/xultimate-remoting/tree/master/xultimate-remoting-cxf 18 | 19 | 20 | 21 | ${project.groupId} 22 | xultimate-remoting-service 23 | ${project.version} 24 | 25 | 26 | org.apache.cxf 27 | cxf-rt-frontend-jaxws 28 | 2.7.4 29 | 30 | 31 | org.apache.cxf 32 | cxf-rt-transports-http 33 | 2.7.4 34 | 35 | 36 | 37 | xultimate-remoting-cxf 38 | 39 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /xultimate-remoting-cxf/result.txt: -------------------------------------------------------------------------------- 1 | 测试过程中出现异常。 2 | ab -c 100 -n 1000 http://127.0.0.1:8081/ultimate-remoting-cxf/accounts 3 | 4 | This is ApacheBench, Version 2.3 <$Revision: 655654 $> 5 | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 6 | Licensed to The Apache Software Foundation, http://www.apache.org/ 7 | 8 | Benchmarking 127.0.0.1 (be patient) 9 | Completed 100 requests 10 | Completed 200 requests 11 | Completed 300 requests 12 | Completed 400 requests 13 | Completed 500 requests 14 | Completed 600 requests 15 | Completed 700 requests 16 | Completed 800 requests 17 | Completed 900 requests 18 | Completed 1000 requests 19 | Finished 1000 requests 20 | 21 | 22 | Server Software: Apache-Coyote/1.1 23 | Server Hostname: 127.0.0.1 24 | Server Port: 8081 25 | 26 | Document Path: /ultimate-remoting-cxf/accounts 27 | Document Length: 773 bytes 28 | 29 | Concurrency Level: 100 30 | Time taken for tests: 0.410 seconds 31 | Complete requests: 1000 32 | Failed requests: 0 33 | Write errors: 0 34 | Total transferred: 959000 bytes 35 | HTML transferred: 773000 bytes 36 | Requests per second: 2437.22 [#/sec] (mean) 37 | Time per request: 41.030 [ms] (mean) 38 | Time per request: 0.410 [ms] (mean, across all concurrent requests) 39 | Transfer rate: 2282.51 [Kbytes/sec] received 40 | 41 | Connection Times (ms) 42 | min mean[+/-sd] median max 43 | Connect: 0 1 2.7 0 11 44 | Processing: 7 38 12.6 35 74 45 | Waiting: 7 38 12.4 35 72 46 | Total: 13 39 11.9 36 74 47 | 48 | Percentage of the requests served within a certain time (ms) 49 | 50% 36 50 | 66% 44 51 | 75% 49 52 | 80% 52 53 | 90% 55 54 | 95% 60 55 | 98% 64 56 | 99% 67 57 | 100% 74 (longest request) -------------------------------------------------------------------------------- /xultimate-remoting-cxf/src/main/java/org/danielli/xultimate/remoting/service/AccountServiceEndpoint.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.service; 2 | 3 | import java.util.List; 4 | 5 | import javax.jws.WebService; 6 | 7 | import org.danielli.xultimate.remoting.dto.Account; 8 | 9 | @WebService 10 | public interface AccountServiceEndpoint { 11 | 12 | void insertAccount(Account acc); 13 | List getAccounts(String name); 14 | List getAllAccounts(); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /xultimate-remoting-cxf/src/main/java/org/danielli/xultimate/remoting/service/cxf/AccountServiceEndpointImpl.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.service.cxf; 2 | 3 | import java.util.List; 4 | 5 | import javax.annotation.Resource; 6 | import javax.jws.WebService; 7 | 8 | import org.danielli.xultimate.remoting.dto.Account; 9 | import org.danielli.xultimate.remoting.service.AccountService; 10 | import org.danielli.xultimate.remoting.service.AccountServiceEndpoint; 11 | import org.springframework.stereotype.Component; 12 | 13 | @WebService(endpointInterface = "org.danielli.xultimate.remoting.service.AccountServiceEndpoint") 14 | @Component("accountServiceEndpoint") 15 | public class AccountServiceEndpointImpl implements AccountServiceEndpoint { 16 | @Resource(name = "accountService") 17 | private AccountService biz; 18 | 19 | public void insertAccount(Account acc) { 20 | biz.insertAccount(acc); 21 | } 22 | 23 | public List getAccounts(String name) { 24 | return biz.getAccounts(name); 25 | } 26 | 27 | public List getAllAccounts() { 28 | return biz.getAllAccounts(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /xultimate-remoting-cxf/src/main/java/org/danielli/xultimate/remoting/web/controller/AccountController.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.web.controller; 2 | 3 | import java.util.List; 4 | 5 | import javax.annotation.Resource; 6 | 7 | import org.danielli.xultimate.remoting.dto.Account; 8 | import org.danielli.xultimate.remoting.service.AccountServiceEndpoint; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.ModelMap; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | 14 | @Controller 15 | @RequestMapping("/accounts") 16 | public class AccountController { 17 | 18 | @Resource(name = "remoteCxfAccountServiceEndpoint") 19 | public AccountServiceEndpoint accountService; 20 | 21 | @RequestMapping(value = "/add", method = { RequestMethod.GET }) 22 | public String toInsertAccount() { 23 | return "account_add"; 24 | } 25 | 26 | @RequestMapping(method = { RequestMethod.POST }) 27 | public String doInsertAccount(Account account, ModelMap modelMap) { 28 | accountService.insertAccount(account); 29 | modelMap.put("name", account.getName()); 30 | return "redirect:/accounts"; 31 | } 32 | 33 | @RequestMapping(method = { RequestMethod.GET }) 34 | public String getAccounts(Account account, ModelMap modelMap) { 35 | List accountList = null; 36 | if (account == null || account.getName() == null) { 37 | accountList = accountService.getAllAccounts(); 38 | } else { 39 | accountList = accountService.getAccounts(account.getName()); 40 | } 41 | modelMap.put("accounts", accountList); 42 | return "account_list"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /xultimate-remoting-cxf/src/main/resources/applicationContext-service-remoting-cxf.xml: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /xultimate-remoting-cxf/src/main/resources/applicationContext-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | import.packages+=org.danielli.xultimate.remoting.dto 40 | template.directory=/WEB-INF/templates/ 41 | input.encoding=UTF-8 42 | output.encoding=UTF-8 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /xultimate-remoting-cxf/src/main/webapp/WEB-INF/templates/account_add.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Add Account 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
18 |
19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-cxf/src/main/webapp/WEB-INF/templates/account_list.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Account List 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
${account.name}
18 | Add Account 19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-cxf/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | isLog4jAutoInitializationDisabled 5 | true 6 | 7 | 8 | 9 | org.apache.logging.log4j.web.Log4jServletContextListener 10 | 11 | 12 | 13 | log4jServletFilter 14 | org.apache.logging.log4j.web.Log4jServletFilter 15 | 16 | 17 | log4jServletFilter 18 | /* 19 | REQUEST 20 | FORWARD 21 | INCLUDE 22 | ERROR 23 | ASYNC 24 | 25 | 26 | 27 | contextConfigLocation 28 | classpath:applicationContext-service.xml 29 | 30 | 31 | 32 | org.springframework.web.context.ContextLoaderListener 33 | 34 | 35 | 36 | cxf 37 | org.apache.cxf.transport.servlet.CXFServlet 38 | 39 | config-location 40 | classpath:applicationContext-service-remoting-cxf.xml 41 | 42 | 1 43 | 44 | 45 | 46 | cxf 47 | /services/* 48 | 49 | 50 | spring 51 | org.springframework.web.servlet.DispatcherServlet 52 | 53 | contextConfigLocation 54 | classpath:applicationContext-servlet.xml 55 | 56 | 57 | 58 | spring 59 | / 60 | 61 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.danielli.xultimate 8 | xultimate-remoting 9 | 1.0.0-SNAPSHOT 10 | 11 | 12 | xultimate-remoting-dubbo 13 | 14 | war 15 | 16 | The X-Ultimate Remoting Dubbo 17 | The X-Ultimate Remoting dubbo project. 18 | https://github.com/daniellitoc/xultimate-remoting/tree/master/xultimate-remoting-dubbo 19 | 20 | 21 | 22 | ${project.groupId} 23 | xultimate-remoting-service 24 | ${project.version} 25 | 26 | 27 | ${project.groupId} 28 | xultimate-context 29 | ${project.version} 30 | 31 | 32 | io.netty 33 | netty-transport 34 | 35 | 36 | io.netty 37 | netty-codec 38 | 39 | 40 | io.netty 41 | netty-handler 42 | 43 | 44 | 45 | 46 | ${project.groupId} 47 | xultimate-webmvc 48 | ${project.version} 49 | 50 | 51 | com.alibaba 52 | dubbo 53 | 2.5.3 54 | 55 | 56 | org.springframework 57 | spring 58 | 59 | 60 | 61 | 62 | org.apache.zookeeper 63 | zookeeper 64 | 3.4.6 65 | 66 | 67 | org.slf4j 68 | slf4j-api 69 | 70 | 71 | org.slf4j 72 | slf4j-log4j12 73 | 74 | 75 | log4j 76 | log4j 77 | 78 | 79 | io.netty 80 | netty 81 | 82 | 83 | 84 | 85 | com.netflix.curator 86 | curator-framework 87 | 1.3.3 88 | 89 | 90 | com.101tec 91 | zkclient 92 | 0.4 93 | 94 | 95 | org.slf4j 96 | slf4j-api 97 | 98 | 99 | org.slf4j 100 | slf4j-log4j12 101 | 102 | 103 | log4j 104 | log4j 105 | 106 | 107 | 108 | 109 | 110 | 111 | xultimate-remoting-dubbo 112 | 113 | 114 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/java/org/danielli/xultimate/remoting/dubbo/container/Main.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.dubbo.container; 2 | 3 | import java.text.SimpleDateFormat; 4 | import java.util.ArrayList; 5 | import java.util.Arrays; 6 | import java.util.Date; 7 | import java.util.List; 8 | 9 | import com.alibaba.dubbo.common.Constants; 10 | import com.alibaba.dubbo.common.extension.ExtensionLoader; 11 | import com.alibaba.dubbo.common.logger.Logger; 12 | import com.alibaba.dubbo.common.logger.LoggerFactory; 13 | import com.alibaba.dubbo.common.utils.ConfigUtils; 14 | import com.alibaba.dubbo.container.Container; 15 | 16 | /** 17 | * Main. (API, Static, ThreadSafe) 18 | * 19 | * @author william.liangf 20 | */ 21 | public class Main { 22 | 23 | public static final String CONTAINER_KEY = "dubbo.container"; 24 | 25 | private static final Logger logger = LoggerFactory.getLogger(Main.class); 26 | 27 | private static final ExtensionLoader loader = ExtensionLoader.getExtensionLoader(Container.class); 28 | 29 | private static volatile boolean running = true; 30 | 31 | public static void main(String[] args) { 32 | try { 33 | if (args == null || args.length == 0) { 34 | String config = ConfigUtils.getProperty(CONTAINER_KEY, loader.getDefaultExtensionName()); 35 | args = Constants.COMMA_SPLIT_PATTERN.split(config); 36 | } 37 | 38 | final List containers = new ArrayList(); 39 | for (int i = 0; i < args.length; i ++) { 40 | containers.add(loader.getExtension(args[i])); 41 | } 42 | logger.info("Use container type(" + Arrays.toString(args) + ") to run dubbo serivce."); 43 | 44 | Runtime.getRuntime().addShutdownHook(new Thread() { 45 | public void run() { 46 | for (Container container : containers) { 47 | try { 48 | container.stop(); 49 | logger.info("Dubbo " + container.getClass().getSimpleName() + " stopped!"); 50 | } catch (Throwable t) { 51 | logger.error(t.getMessage(), t); 52 | } 53 | synchronized (Main.class) { 54 | running = false; 55 | Main.class.notify(); 56 | } 57 | } 58 | } 59 | }); 60 | 61 | for (Container container : containers) { 62 | container.start(); 63 | logger.info("Dubbo " + container.getClass().getSimpleName() + " started!"); 64 | } 65 | System.out.println(new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]").format(new Date()) + " Dubbo service server started!"); 66 | } catch (RuntimeException e) { 67 | e.printStackTrace(); 68 | logger.error(e.getMessage(), e); 69 | System.exit(1); 70 | } 71 | synchronized (Main.class) { 72 | while (running) { 73 | try { 74 | Main.class.wait(); 75 | } catch (Throwable e) { 76 | } 77 | } 78 | } 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/java/org/danielli/xultimate/remoting/dubbo/container/spring/SpringContainer.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.dubbo.container.spring; 2 | 3 | import org.danielli.xultimate.util.Assert; 4 | import org.springframework.context.support.ClassPathXmlApplicationContext; 5 | 6 | import com.alibaba.dubbo.common.logger.Logger; 7 | import com.alibaba.dubbo.common.logger.LoggerFactory; 8 | import com.alibaba.dubbo.common.utils.ConfigUtils; 9 | import com.alibaba.dubbo.container.Container; 10 | 11 | /** 12 | * SpringContainer. (SPI, Singleton, ThreadSafe) 13 | * 14 | * @author william.liangf 15 | */ 16 | public class SpringContainer implements Container { 17 | 18 | private static final Logger logger = LoggerFactory.getLogger(SpringContainer.class); 19 | 20 | public static final String SPRING_CONFIG = "dubbo.spring.config"; 21 | 22 | static ClassPathXmlApplicationContext context; 23 | 24 | public static ClassPathXmlApplicationContext getContext() { 25 | return context; 26 | } 27 | 28 | public void start() { 29 | String configPath = ConfigUtils.getProperty(SPRING_CONFIG); 30 | Assert.hasLength(configPath, "you must set `dubbo.spring.config` in dubbo.properties"); 31 | context = new ClassPathXmlApplicationContext(configPath.split("[,\\s]+")); 32 | context.start(); 33 | } 34 | 35 | public void stop() { 36 | try { 37 | if (context != null) { 38 | context.stop(); 39 | context.close(); 40 | context = null; 41 | } 42 | } catch (Throwable e) { 43 | logger.error(e.getMessage(), e); 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/java/org/danielli/xultimate/remoting/dubbo/serialize/support/ObjectInput.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.dubbo.serialize.support; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.lang.reflect.Type; 6 | 7 | import org.danielli.xultimate.core.compression.Decompressor; 8 | import org.danielli.xultimate.core.io.AbstractObjectInput; 9 | 10 | /** 11 | * 对象输入流。 12 | * 13 | * @author Daniel Li 14 | * @since 18 Jun 2013 15 | */ 16 | public class ObjectInput implements com.alibaba.dubbo.common.serialize.ObjectInput { 17 | 18 | protected AbstractObjectInput objectInput; 19 | 20 | public ObjectInput(AbstractObjectInput objectInput) { 21 | this.objectInput = objectInput; 22 | } 23 | 24 | public ObjectInput(AbstractObjectInput objectInput, InputStream inputStream, Decompressor decompressor) throws IOException { 25 | this.objectInput = objectInput; 26 | byte[] hasCompress = new byte[1]; 27 | inputStream.read(hasCompress); 28 | if (hasCompress[0] == 1) { 29 | this.objectInput.setInputStream(decompressor.wrapper(inputStream)); 30 | } else { 31 | this.objectInput.setInputStream(inputStream); 32 | } 33 | } 34 | 35 | @Override 36 | public boolean readBool() throws IOException { 37 | return objectInput.readBoolean(); 38 | } 39 | 40 | @Override 41 | public byte readByte() throws IOException { 42 | return objectInput.readByte(); 43 | } 44 | 45 | @Override 46 | public short readShort() throws IOException { 47 | return objectInput.readShort(); 48 | } 49 | 50 | @Override 51 | public int readInt() throws IOException { 52 | return objectInput.readInt(true); 53 | } 54 | 55 | @Override 56 | public long readLong() throws IOException { 57 | return objectInput.readLong(true); 58 | } 59 | 60 | @Override 61 | public float readFloat() throws IOException { 62 | return objectInput.readFloat(); 63 | } 64 | 65 | @Override 66 | public double readDouble() throws IOException { 67 | return objectInput.readDouble(); 68 | } 69 | 70 | @Override 71 | public String readUTF() throws IOException { 72 | return objectInput.readString(); 73 | } 74 | 75 | @Override 76 | public byte[] readBytes() throws IOException { 77 | int len = objectInput.readInt(true); 78 | if (len == -1) { 79 | return null; 80 | } else { 81 | return objectInput.readBytes(len); 82 | } 83 | } 84 | 85 | @Override 86 | public Object readObject() throws IOException, ClassNotFoundException { 87 | return objectInput.readObject(); 88 | } 89 | 90 | @Override 91 | public T readObject(Class cls) throws IOException, ClassNotFoundException { 92 | return objectInput.readObject(cls); 93 | } 94 | 95 | @Override 96 | public T readObject(Class cls, Type type) throws IOException, ClassNotFoundException { 97 | return objectInput.readObject(cls); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/java/org/danielli/xultimate/remoting/dubbo/serialize/support/ObjectOutput.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.dubbo.serialize.support; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | 6 | import org.danielli.xultimate.core.compression.Compressor; 7 | import org.danielli.xultimate.core.io.AbstractObjectOutput; 8 | import org.danielli.xultimate.core.serializer.java.util.SerializerUtils; 9 | 10 | /** 11 | * 对象输出流。 12 | * 13 | * @author Daniel Li 14 | * @since 18 Jun 2013 15 | */ 16 | public class ObjectOutput implements com.alibaba.dubbo.common.serialize.ObjectOutput { 17 | 18 | protected AbstractObjectOutput objectOutput; 19 | 20 | protected OutputStream outputStream; 21 | 22 | protected int compressionThreshold; 23 | 24 | protected Compressor compressor; 25 | 26 | public ObjectOutput(AbstractObjectOutput objectOutput, OutputStream outputStream, int compressionThreshold, Compressor compressor) { 27 | this.objectOutput = objectOutput; 28 | this.outputStream = outputStream; 29 | this.compressionThreshold = compressionThreshold; 30 | this.compressor = compressor; 31 | } 32 | 33 | @Override 34 | public void writeBool(boolean v) throws IOException { 35 | objectOutput.writeBoolean(v); 36 | } 37 | 38 | @Override 39 | public void writeByte(byte v) throws IOException { 40 | objectOutput.writeByte(v); 41 | } 42 | 43 | @Override 44 | public void writeShort(short v) throws IOException { 45 | objectOutput.writeShort(v); 46 | } 47 | 48 | @Override 49 | public void writeInt(int v) throws IOException { 50 | objectOutput.writeInt(v, true); 51 | } 52 | 53 | @Override 54 | public void writeLong(long v) throws IOException { 55 | objectOutput.writeLong(v, true); 56 | } 57 | 58 | @Override 59 | public void writeFloat(float v) throws IOException { 60 | objectOutput.writeFloat(v); 61 | } 62 | 63 | @Override 64 | public void writeDouble(double v) throws IOException { 65 | objectOutput.writeDouble(v); 66 | } 67 | 68 | @Override 69 | public void writeUTF(String v) throws IOException { 70 | objectOutput.writeString(v); 71 | } 72 | 73 | @Override 74 | public void writeBytes(byte[] v) throws IOException { 75 | if (v == null) { 76 | objectOutput.writeInt(-1, true); 77 | } else { 78 | writeBytes(v, 0, v.length); 79 | } 80 | } 81 | 82 | @Override 83 | public void writeBytes(byte[] v, int off, int len) throws IOException { 84 | if (v == null) { 85 | objectOutput.writeInt(-1, true); 86 | } else { 87 | objectOutput.writeInt(len, true); 88 | objectOutput.writeBytes(v, off, len); 89 | } 90 | } 91 | 92 | @Override 93 | public void flushBuffer() throws IOException { 94 | try { 95 | if (objectOutput.position() > compressionThreshold) { 96 | outputStream.write(SerializerUtils.encodeByte((byte) 1)); 97 | outputStream.write(compressor.compress(objectOutput.toBytes())); 98 | } else { 99 | outputStream.write(SerializerUtils.encodeByte((byte) 0)); 100 | outputStream.write(objectOutput.getBuffer(), 0, objectOutput.position()); 101 | } 102 | } finally { 103 | objectOutput.close(); 104 | outputStream.flush(); 105 | } 106 | } 107 | 108 | @Override 109 | public void writeObject(Object obj) throws IOException { 110 | objectOutput.writeObject(obj); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/java/org/danielli/xultimate/remoting/dubbo/serialize/support/java/JavaSerialization.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.dubbo.serialize.support.java; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | 7 | import org.danielli.xultimate.core.compression.Compressor; 8 | import org.danielli.xultimate.core.compression.Decompressor; 9 | import org.danielli.xultimate.core.compression.support.SnappyJavaCompressor; 10 | import org.danielli.xultimate.core.io.support.JavaObjectInput; 11 | import org.danielli.xultimate.core.io.support.JavaObjectOutput; 12 | import org.danielli.xultimate.remoting.dubbo.serialize.support.ObjectInput; 13 | import org.danielli.xultimate.remoting.dubbo.serialize.support.ObjectOutput; 14 | 15 | import com.alibaba.dubbo.common.URL; 16 | import com.alibaba.dubbo.common.serialize.Serialization; 17 | 18 | /** 19 | * Java序列化器。 20 | * 21 | * @author Daniel Li 22 | * @since 18 Jun 2013 23 | */ 24 | public class JavaSerialization implements Serialization { 25 | 26 | protected int bufferSize = 256; 27 | 28 | protected Compressor compressor = SnappyJavaCompressor.COMPRESSOR; 29 | 30 | protected Decompressor decompressor = SnappyJavaCompressor.COMPRESSOR; 31 | 32 | protected int compressionThreshold = 512; 33 | 34 | @Override 35 | public byte getContentTypeId() { 36 | return 13; 37 | } 38 | 39 | @Override 40 | public String getContentType() { 41 | return "x-application/java"; 42 | } 43 | 44 | @Override 45 | public com.alibaba.dubbo.common.serialize.ObjectOutput serialize(URL url, OutputStream output) throws IOException { 46 | return new ObjectOutput(new JavaObjectOutput(bufferSize), output, compressionThreshold, compressor); 47 | } 48 | 49 | @Override 50 | public com.alibaba.dubbo.common.serialize.ObjectInput deserialize(URL url, InputStream input) throws IOException { 51 | byte[] hasCompress = new byte[1]; 52 | input.read(hasCompress); 53 | if (hasCompress[0] == 1) { 54 | return new ObjectInput(new JavaObjectInput(decompressor.wrapper(input), bufferSize)); 55 | } else { 56 | return new ObjectInput(new JavaObjectInput(input, bufferSize)); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/java/org/danielli/xultimate/remoting/dubbo/serialize/support/kryo/KryoSerialization.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.dubbo.serialize.support.kryo; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | 7 | import org.danielli.xultimate.core.compression.Compressor; 8 | import org.danielli.xultimate.core.compression.Decompressor; 9 | import org.danielli.xultimate.core.compression.support.SnappyJavaCompressor; 10 | import org.danielli.xultimate.core.io.support.RpcKryoObjectInput; 11 | import org.danielli.xultimate.core.io.support.RpcKryoObjectOutput; 12 | import org.danielli.xultimate.core.serializer.kryo.support.ThreadLocalKryoGenerator; 13 | import org.danielli.xultimate.remoting.dubbo.serialize.support.ObjectInput; 14 | import org.danielli.xultimate.remoting.dubbo.serialize.support.ObjectOutput; 15 | 16 | import com.alibaba.dubbo.common.URL; 17 | import com.alibaba.dubbo.common.serialize.Serialization; 18 | 19 | /** 20 | * Kryo序列化器。 21 | * 22 | * @author Daniel Li 23 | * @since 18 Jun 2013 24 | */ 25 | public class KryoSerialization implements Serialization { 26 | 27 | protected int bufferSize = 256; 28 | 29 | protected Compressor compressor = SnappyJavaCompressor.COMPRESSOR; 30 | 31 | protected Decompressor decompressor = SnappyJavaCompressor.COMPRESSOR; 32 | 33 | protected int compressionThreshold = 512; 34 | 35 | public byte getContentTypeId() { 36 | return 12; 37 | } 38 | 39 | public String getContentType() { 40 | return "x-application/kryo"; 41 | } 42 | 43 | @Override 44 | public com.alibaba.dubbo.common.serialize.ObjectOutput serialize(URL url, OutputStream output) throws IOException { 45 | return new ObjectOutput(new RpcKryoObjectOutput(bufferSize, ThreadLocalKryoGenerator.INSTANCE.generate()), output, compressionThreshold, compressor); 46 | } 47 | 48 | @Override 49 | public com.alibaba.dubbo.common.serialize.ObjectInput deserialize(URL url, InputStream input) throws IOException { 50 | return new ObjectInput(new RpcKryoObjectInput(bufferSize, ThreadLocalKryoGenerator.INSTANCE.generate()), input, decompressor); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/java/org/danielli/xultimate/remoting/dubbo/serialize/support/protobuf/ProtobufSerialization.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.dubbo.serialize.support.protobuf; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | 7 | import org.danielli.xultimate.core.compression.Compressor; 8 | import org.danielli.xultimate.core.compression.Decompressor; 9 | import org.danielli.xultimate.core.compression.support.SnappyJavaCompressor; 10 | import org.danielli.xultimate.core.io.support.RpcProtobufObjectInput; 11 | import org.danielli.xultimate.core.io.support.RpcProtobufObjectOutput; 12 | import org.danielli.xultimate.core.serializer.kryo.support.ThreadLocalKryoGenerator; 13 | import org.danielli.xultimate.core.serializer.protostuff.util.LinkedBufferUtils; 14 | import org.danielli.xultimate.remoting.dubbo.serialize.support.ObjectInput; 15 | import org.danielli.xultimate.remoting.dubbo.serialize.support.ObjectOutput; 16 | 17 | import com.alibaba.dubbo.common.URL; 18 | import com.alibaba.dubbo.common.serialize.Serialization; 19 | 20 | /** 21 | * Protobuf序列化器。 22 | * 23 | * @author Daniel Li 24 | * @since 18 Jun 2013 25 | */ 26 | public class ProtobufSerialization implements Serialization { 27 | 28 | protected int bufferSize = 256; 29 | 30 | protected Compressor compressor = SnappyJavaCompressor.COMPRESSOR; 31 | 32 | protected Decompressor decompressor = SnappyJavaCompressor.COMPRESSOR; 33 | 34 | protected int compressionThreshold = 512; 35 | 36 | public byte getContentTypeId() { 37 | return 11; 38 | } 39 | 40 | public String getContentType() { 41 | return "x-application/protobuf"; 42 | } 43 | 44 | @Override 45 | public com.alibaba.dubbo.common.serialize.ObjectOutput serialize(URL url, OutputStream output) throws IOException { 46 | return new ObjectOutput(new RpcProtobufObjectOutput(bufferSize, LinkedBufferUtils.getCurrentLinkedBuffer(bufferSize), ThreadLocalKryoGenerator.INSTANCE.generate()), output, compressionThreshold, compressor); 47 | } 48 | 49 | @Override 50 | public com.alibaba.dubbo.common.serialize.ObjectInput deserialize(URL url, InputStream input) throws IOException { 51 | return new ObjectInput(new RpcProtobufObjectInput(bufferSize, ThreadLocalKryoGenerator.INSTANCE.generate()), input, decompressor); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/java/org/danielli/xultimate/remoting/dubbo/serialize/support/protostuff/ProtostuffSerialization.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.dubbo.serialize.support.protostuff; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | 7 | import org.danielli.xultimate.core.compression.Compressor; 8 | import org.danielli.xultimate.core.compression.Decompressor; 9 | import org.danielli.xultimate.core.compression.support.SnappyJavaCompressor; 10 | import org.danielli.xultimate.core.io.support.RpcProtostuffObjectInput; 11 | import org.danielli.xultimate.core.io.support.RpcProtostuffObjectOutput; 12 | import org.danielli.xultimate.core.serializer.kryo.support.ThreadLocalKryoGenerator; 13 | import org.danielli.xultimate.core.serializer.protostuff.util.LinkedBufferUtils; 14 | import org.danielli.xultimate.remoting.dubbo.serialize.support.ObjectInput; 15 | import org.danielli.xultimate.remoting.dubbo.serialize.support.ObjectOutput; 16 | 17 | import com.alibaba.dubbo.common.URL; 18 | import com.alibaba.dubbo.common.serialize.Serialization; 19 | 20 | /** 21 | * Protostuff序列化器。 22 | * 23 | * @author Daniel Li 24 | * @since 18 Jun 2013 25 | */ 26 | public class ProtostuffSerialization implements Serialization { 27 | 28 | protected int bufferSize = 256; 29 | 30 | protected Compressor compressor = SnappyJavaCompressor.COMPRESSOR; 31 | 32 | protected Decompressor decompressor = SnappyJavaCompressor.COMPRESSOR; 33 | 34 | protected int compressionThreshold = 512; 35 | 36 | public byte getContentTypeId() { 37 | return 10; 38 | } 39 | 40 | public String getContentType() { 41 | return "x-application/protostuff"; 42 | } 43 | 44 | @Override 45 | public com.alibaba.dubbo.common.serialize.ObjectOutput serialize(URL url, OutputStream output) throws IOException { 46 | return new ObjectOutput(new RpcProtostuffObjectOutput(bufferSize, LinkedBufferUtils.getCurrentLinkedBuffer(bufferSize), ThreadLocalKryoGenerator.INSTANCE.generate()), output, compressionThreshold, compressor); 47 | } 48 | 49 | @Override 50 | public com.alibaba.dubbo.common.serialize.ObjectInput deserialize(URL url, InputStream input) throws IOException { 51 | return new ObjectInput(new RpcProtostuffObjectInput(bufferSize, ThreadLocalKryoGenerator.INSTANCE.generate()), input, decompressor); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/java/org/danielli/xultimate/remoting/web/controller/AccountController.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.web.controller; 2 | 3 | import java.util.List; 4 | 5 | import javax.annotation.Resource; 6 | 7 | import org.danielli.xultimate.remoting.dto.Account; 8 | import org.danielli.xultimate.remoting.service.AccountService; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.ModelMap; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | 14 | /** 15 | * 客户端和服务端都在一个jvm实例上,是有问题的。看测试。 16 | * 17 | * @author Daniel Li 18 | * @since 18 Jun 2013 19 | */ 20 | @Controller 21 | @RequestMapping("/accounts") 22 | public class AccountController { 23 | 24 | @Resource(name = "remotingDubboAccountService") 25 | public AccountService accountService; 26 | 27 | @RequestMapping(value = "/add", method = { RequestMethod.GET }) 28 | public String toInsertAccount() { 29 | return "account_add"; 30 | } 31 | 32 | @RequestMapping(method = { RequestMethod.POST }) 33 | public String doInsertAccount(Account account, ModelMap modelMap) { 34 | accountService.insertAccount(account); 35 | modelMap.put("name", account.getName()); 36 | return "redirect:/accounts"; 37 | } 38 | 39 | @RequestMapping(method = { RequestMethod.GET }) 40 | public String getAccounts(Account account, ModelMap modelMap) { 41 | List accountList = null; 42 | if (account == null || account.getName() == null) { 43 | accountList = accountService.getAllAccounts(); 44 | } else { 45 | accountList = accountService.getAccounts(account.getName()); 46 | } 47 | modelMap.put("accounts", accountList); 48 | return "account_list"; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/java/org/danielli/xultimate/zookeeper/CuratorFrameworkFactoryBean.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.zookeeper; 2 | 3 | import org.danielli.xultimate.util.StringUtils; 4 | import org.springframework.beans.factory.FactoryBean; 5 | 6 | import com.netflix.curator.RetryPolicy; 7 | import com.netflix.curator.framework.CuratorFramework; 8 | import com.netflix.curator.framework.CuratorFrameworkFactory; 9 | import com.netflix.curator.framework.CuratorFrameworkFactory.Builder; 10 | 11 | public class CuratorFrameworkFactoryBean implements FactoryBean { 12 | 13 | protected String connectString; 14 | 15 | protected int sessionTimeoutMs = 60000; 16 | 17 | protected int connectionTimeoutMs = 15000; 18 | 19 | protected RetryPolicy retryPolicy; 20 | 21 | protected String username; 22 | 23 | protected String password; 24 | 25 | private CuratorFramework curatorFramework; 26 | 27 | @Override 28 | public CuratorFramework getObject() throws Exception { 29 | Builder builder = CuratorFrameworkFactory.builder().connectString(connectString) 30 | .sessionTimeoutMs(sessionTimeoutMs) 31 | .connectionTimeoutMs(connectionTimeoutMs) 32 | .retryPolicy(retryPolicy); 33 | if (StringUtils.isBlank(username) && StringUtils.isBlank(password)) { 34 | curatorFramework = builder.build(); 35 | } else { 36 | curatorFramework = builder.authorization("digest", new StringBuilder(username).append(":").append(password).toString().getBytes()).build(); 37 | } 38 | 39 | curatorFramework.start(); 40 | 41 | return curatorFramework; 42 | } 43 | 44 | public void close() { 45 | curatorFramework.close(); 46 | } 47 | 48 | @Override 49 | public Class getObjectType() { 50 | return CuratorFramework.class; 51 | } 52 | 53 | @Override 54 | public boolean isSingleton() { 55 | return true; 56 | } 57 | 58 | public void setConnectString(String connectString) { 59 | this.connectString = connectString; 60 | } 61 | 62 | public void setSessionTimeoutMs(int sessionTimeoutMs) { 63 | this.sessionTimeoutMs = sessionTimeoutMs; 64 | } 65 | 66 | public void setConnectionTimeoutMs(int connectionTimeoutMs) { 67 | this.connectionTimeoutMs = connectionTimeoutMs; 68 | } 69 | 70 | public void setRetryPolicy(RetryPolicy retryPolicy) { 71 | this.retryPolicy = retryPolicy; 72 | } 73 | 74 | public void setUsername(String username) { 75 | this.username = username; 76 | } 77 | 78 | public void setPassword(String password) { 79 | this.password = password; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/java/org/danielli/xultimate/zookeeper/SetACLCommandExecutor.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.zookeeper; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import org.apache.zookeeper.data.ACL; 7 | import org.apache.zookeeper.data.Stat; 8 | import org.danielli.xultimate.util.Assert; 9 | import org.springframework.beans.factory.InitializingBean; 10 | 11 | import com.netflix.curator.framework.CuratorFramework; 12 | import com.netflix.curator.framework.api.BackgroundPathAndBytesable; 13 | import com.netflix.curator.framework.api.BackgroundPathable; 14 | 15 | public class SetACLCommandExecutor implements InitializingBean { 16 | 17 | protected boolean inBackground = false; 18 | 19 | protected Map> setACLDatas; 20 | 21 | protected CuratorFramework curatorFramework; 22 | 23 | protected boolean createIfNoExists = true; 24 | 25 | @Override 26 | public void afterPropertiesSet() throws Exception { 27 | Assert.notNull(curatorFramework, "this property `curatorFramework` is required; it must not be null"); 28 | Assert.notEmpty(setACLDatas, "this property `setACLDatas` map must not be empty; it must contain at least one entry"); 29 | 30 | for (Map.Entry> entry : setACLDatas.entrySet()) { 31 | boolean nodeExists = false; 32 | if (curatorFramework.checkExists().forPath(entry.getKey()) != null) { 33 | nodeExists = true; 34 | } else if (createIfNoExists) { 35 | BackgroundPathAndBytesable backgroundPathAndBytesable = curatorFramework.create().withACL(entry.getValue()); 36 | if (inBackground) { 37 | backgroundPathAndBytesable.inBackground().forPath(entry.getKey()); 38 | } else { 39 | backgroundPathAndBytesable.forPath(entry.getKey()); 40 | } 41 | } 42 | if (nodeExists) { 43 | BackgroundPathable backgroundPathable = curatorFramework.setACL().withACL(entry.getValue()); 44 | if (inBackground) { 45 | backgroundPathable.inBackground().forPath(entry.getKey()); 46 | } else { 47 | backgroundPathable.forPath(entry.getKey()); 48 | } 49 | } 50 | } 51 | } 52 | 53 | public void setInBackground(boolean inBackground) { 54 | this.inBackground = inBackground; 55 | } 56 | 57 | public void setSetACLDatas(Map> setACLDatas) { 58 | this.setACLDatas = setACLDatas; 59 | } 60 | 61 | public void setCuratorFramework(CuratorFramework curatorFramework) { 62 | this.curatorFramework = curatorFramework; 63 | } 64 | 65 | public void setCreateIfNoExists(boolean createIfNoExists) { 66 | this.createIfNoExists = createIfNoExists; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.common.serialize.Serialization: -------------------------------------------------------------------------------- 1 | protostuff=org.danielli.xultimate.remoting.dubbo.serialize.support.protostuff.ProtostuffSerialization 2 | kryo=org.danielli.xultimate.remoting.dubbo.serialize.support.kryo.KryoSerialization 3 | protobuf=org.danielli.xultimate.remoting.dubbo.serialize.support.protobuf.ProtobufSerialization 4 | customJava=org.danielli.xultimate.remoting.dubbo.serialize.support.java.JavaSerialization -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.container.Container: -------------------------------------------------------------------------------- 1 | spring=org.danielli.xultimate.remoting.dubbo.container.spring.SpringContainer -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/resources/applicationContext-service-remoting-dubbo-client.xml: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 44 | 45 | 46 | 49 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/resources/applicationContext-service-remoting-dubbo-server.xml: -------------------------------------------------------------------------------- 1 | 2 | 31 | 32 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/resources/applicationContext-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | import.packages+=org.danielli.xultimate.remoting.dto 38 | template.directory=/WEB-INF/templates/ 39 | input.encoding=UTF-8 40 | output.encoding=UTF-8 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/resources/dubbo.properties: -------------------------------------------------------------------------------- 1 | dubbo.spring.config=applicationContext-service.xml,applicationContext-service-remoting-dubbo-server.xml -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/webapp/WEB-INF/templates/account_add.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Add Account 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
18 |
19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/webapp/WEB-INF/templates/account_list.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Account List 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
${account.name}
18 | Add Account 19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | isLog4jAutoInitializationDisabled 5 | true 6 | 7 | 8 | 9 | org.apache.logging.log4j.web.Log4jServletContextListener 10 | 11 | 12 | 13 | log4jServletFilter 14 | org.apache.logging.log4j.web.Log4jServletFilter 15 | 16 | 17 | log4jServletFilter 18 | /* 19 | REQUEST 20 | FORWARD 21 | INCLUDE 22 | ERROR 23 | ASYNC 24 | 25 | 26 | 27 | contextConfigLocation 28 | classpath:applicationContext-service.xml, classpath:applicationContext-service-remoting-dubbo.xml 29 | 30 | 31 | org.springframework.web.context.ContextLoaderListener 32 | 33 | 34 | 35 | spring 36 | org.springframework.web.servlet.DispatcherServlet 37 | 38 | contextConfigLocation 39 | classpath:applicationContext-servlet.xml 40 | 41 | 42 | 43 | spring 44 | / 45 | 46 | -------------------------------------------------------------------------------- /xultimate-remoting-dubbo/src/test/java/org/danielli/xultimate/remoting/dubbo/serialize/Consumer.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.dubbo.serialize; 2 | import org.danielli.xultimate.remoting.dto.Account; 3 | import org.danielli.xultimate.remoting.service.AccountService; 4 | import org.danielli.xultimate.util.performance.PerformanceMonitor; 5 | import org.danielli.xultimate.util.time.stopwatch.support.AdvancedStopWatchSummary; 6 | import org.springframework.context.support.ClassPathXmlApplicationContext; 7 | 8 | 9 | public class Consumer { 10 | public static void main(String[] args) throws Exception { 11 | ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext-service-remoting-dubbo-client.xml"}); 12 | context.start(); 13 | 14 | AccountService demoService = (AccountService)context.getBean("remotingDubboAccountService"); // 获取远程服务代理 15 | 16 | PerformanceMonitor.start("Dubbo Performance Test"); 17 | for (int i = 0; i < 3; i++) { 18 | for (int j = 0; j < 50000; j++) { 19 | Account account = new Account(); 20 | account.setName("Daniel Li"); 21 | demoService.insertAccount(account); // 执行远程方法 22 | System.out.println(j); 23 | } 24 | PerformanceMonitor.mark("dubbo" + i); 25 | } 26 | PerformanceMonitor.stop(); 27 | PerformanceMonitor.summarize(new AdvancedStopWatchSummary(true)); 28 | PerformanceMonitor.remove(); 29 | // dubbo start timestamp(ns): 989258276356, stop timestamp(ns): 1045624291663, running time: 0000:00:00 0:00:56.366 (56366015307 ns) (56366015 us) (56366 ms) (029.33839%) 30 | // hessian2 start timestamp(ns): 1296299303505, stop timestamp(ns): 1352769635210, running time: 0000:00:00 0:00:56.470 (56470331705 ns) (56470331 us) (56470 ms) (029.29963%) 31 | // java start timestamp(ns): 5826432023255, stop timestamp(ns): 5887835317613, running time: 0000:00:00 0:01:01.403 (61403294358 ns) (61403294 us) (61403 ms) (018.26744%) 32 | // compactedjava 33 | // customJava start timestamp(ns): 2831795239652, stop timestamp(ns): 2893496929263, running time: 0000:00:00 0:01:01.701 (61701689611 ns) (61701689 us) (61701 ms) (029.44951%) 34 | // kryo start timestamp(ns): 3413941430671, stop timestamp(ns): 3469853249738, running time: 0000:00:00 0:00:55.911 (55911819067 ns) (55911819 us) (55911 ms) (029.36789%) 35 | // protobuf start timestamp(ns): 8282527284369, stop timestamp(ns): 8340615324311, running time: 0000:00:00 0:00:58.088 (58088039942 ns) (58088039 us) (58088 ms) (029.14129%) 36 | // protostuff start timestamp(ns): 11678533456635, stop timestamp(ns): 11738213938152, running time: 0000:00:00 0:00:59.680 (59680481517 ns) (59680481 us) (59680 ms) (028.95920%) 37 | context.close(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /xultimate-remoting-hessian/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.danielli.xultimate 8 | xultimate-remoting 9 | 1.0.0-SNAPSHOT 10 | 11 | xultimate-remoting-hessian 12 | war 13 | 14 | The X-Ultimate Remoting Hessian 15 | The X-Ultimate Remoting hessian project. 16 | https://github.com/daniellitoc/xultimate-remoting/tree/master/xultimate-remoting-hessian 17 | 18 | 19 | 20 | com.caucho 21 | hessian 22 | 4.0.7 23 | 24 | 25 | ${project.groupId} 26 | xultimate-remoting-service 27 | ${project.version} 28 | 29 | 30 | 31 | 32 | xultimate-remoting-hessian 33 | 34 | 35 | -------------------------------------------------------------------------------- /xultimate-remoting-hessian/result.txt: -------------------------------------------------------------------------------- 1 | 测试过程中出现了异常。 2 | ab -c 100 -n 1000 http://127.0.0.1:8081/xultimate-remoting-hessian/accounts 3 | 4 | This is ApacheBench, Version 2.3 <$Revision: 655654 $> 5 | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 6 | Licensed to The Apache Software Foundation, http://www.apache.org/ 7 | 8 | Benchmarking 127.0.0.1 (be patient) 9 | Completed 100 requests 10 | Completed 200 requests 11 | Completed 300 requests 12 | Completed 400 requests 13 | Completed 500 requests 14 | Completed 600 requests 15 | Completed 700 requests 16 | Completed 800 requests 17 | Completed 900 requests 18 | Completed 1000 requests 19 | Finished 1000 requests 20 | 21 | 22 | Server Software: Apache-Coyote/1.1 23 | Server Hostname: 127.0.0.1 24 | Server Port: 8081 25 | 26 | Document Path: /xultimate-remoting-hessian/accounts 27 | Document Length: 807 bytes 28 | 29 | Concurrency Level: 100 30 | Time taken for tests: 0.250 seconds 31 | Complete requests: 1000 32 | Failed requests: 0 33 | Write errors: 0 34 | Total transferred: 993000 bytes 35 | HTML transferred: 807000 bytes 36 | Requests per second: 4001.02 [#/sec] (mean) 37 | Time per request: 24.994 [ms] (mean) 38 | Time per request: 0.250 [ms] (mean, across all concurrent requests) 39 | Transfer rate: 3879.90 [Kbytes/sec] received 40 | 41 | Connection Times (ms) 42 | min mean[+/-sd] median max 43 | Connect: 0 1 3.2 0 13 44 | Processing: 2 23 8.0 22 50 45 | Waiting: 2 22 7.9 22 50 46 | Total: 8 24 6.9 23 50 47 | 48 | Percentage of the requests served within a certain time (ms) 49 | 50% 23 50 | 66% 27 51 | 75% 29 52 | 80% 31 53 | 90% 33 54 | 95% 36 55 | 98% 39 56 | 99% 40 57 | 100% 50 (longest request) -------------------------------------------------------------------------------- /xultimate-remoting-hessian/src/main/java/org/danielli/xultimate/remoting/web/controller/AccountController.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.web.controller; 2 | 3 | import java.util.List; 4 | 5 | import javax.annotation.Resource; 6 | 7 | import org.danielli.xultimate.remoting.dto.Account; 8 | import org.danielli.xultimate.remoting.service.AccountService; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.ModelMap; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | 14 | @Controller 15 | @RequestMapping("/accounts") 16 | public class AccountController { 17 | 18 | @Resource(name = "remotingHessianAccountService") 19 | public AccountService accountService; 20 | 21 | @RequestMapping(value = "/add", method = { RequestMethod.GET }) 22 | public String toInsertAccount() { 23 | return "account_add"; 24 | } 25 | 26 | @RequestMapping(method = { RequestMethod.POST }) 27 | public String doInsertAccount(Account account, ModelMap modelMap) { 28 | accountService.insertAccount(account); 29 | modelMap.put("name", account.getName()); 30 | return "redirect:/accounts"; 31 | } 32 | 33 | @RequestMapping(method = { RequestMethod.GET }) 34 | public String getAccounts(Account account, ModelMap modelMap) { 35 | List accountList = null; 36 | if (account == null || account.getName() == null) { 37 | accountList = accountService.getAllAccounts(); 38 | } else { 39 | accountList = accountService.getAccounts(account.getName()); 40 | } 41 | modelMap.put("accounts", accountList); 42 | return "account_list"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /xultimate-remoting-hessian/src/main/resources/applicationContext-service-remoting-hessian.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /xultimate-remoting-hessian/src/main/resources/applicationContext-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | import.packages+=org.danielli.xultimate.remoting.dto 38 | template.directory=/WEB-INF/templates/ 39 | input.encoding=UTF-8 40 | output.encoding=UTF-8 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /xultimate-remoting-hessian/src/main/webapp/WEB-INF/templates/account_add.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Add Account 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
18 |
19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-hessian/src/main/webapp/WEB-INF/templates/account_list.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Account List 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
${account.name}
18 | Add Account 19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-hessian/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | isLog4jAutoInitializationDisabled 5 | true 6 | 7 | 8 | 9 | org.apache.logging.log4j.web.Log4jServletContextListener 10 | 11 | 12 | 13 | log4jServletFilter 14 | org.apache.logging.log4j.web.Log4jServletFilter 15 | 16 | 17 | log4jServletFilter 18 | /* 19 | REQUEST 20 | FORWARD 21 | INCLUDE 22 | ERROR 23 | ASYNC 24 | 25 | 26 | 27 | contextConfigLocation 28 | classpath:applicationContext-service.xml, classpath:applicationContext-service-remoting-hessian.xml 29 | 30 | 31 | org.springframework.web.context.ContextLoaderListener 32 | 33 | 34 | 35 | spring 36 | org.springframework.web.servlet.DispatcherServlet 37 | 38 | contextConfigLocation 39 | classpath:applicationContext-servlet.xml 40 | 41 | 42 | 43 | spring 44 | / 45 | 46 | -------------------------------------------------------------------------------- /xultimate-remoting-httpinvoker/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.danielli.xultimate 8 | xultimate-remoting 9 | 1.0.0-SNAPSHOT 10 | 11 | 12 | xultimate-remoting-httpinvoker 13 | war 14 | 15 | The X-Ultimate Remoting HttpInvoker 16 | The X-Ultimate Remoting httpinvoker project. 17 | https://github.com/daniellitoc/xultimate-remoting/tree/master/xultimate-remoting-httpinvoker 18 | 19 | 20 | 21 | org.apache.httpcomponents 22 | httpclient 23 | 4.2.3 24 | 25 | 26 | ${project.groupId} 27 | xultimate-remoting-service 28 | ${project.version} 29 | 30 | 31 | 32 | 33 | xultimate-remoting-httpinvoker 34 | 35 | 36 | -------------------------------------------------------------------------------- /xultimate-remoting-httpinvoker/result.txt: -------------------------------------------------------------------------------- 1 | ab -c 100 -n 1000 http://127.0.0.1:8081/xultimate-remoting-httpinvoker/accounts 2 | 3 | This is ApacheBench, Version 2.3 <$Revision: 655654 $> 4 | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 5 | Licensed to The Apache Software Foundation, http://www.apache.org/ 6 | 7 | Benchmarking 127.0.0.1 (be patient) 8 | Completed 100 requests 9 | Completed 200 requests 10 | Completed 300 requests 11 | Completed 400 requests 12 | Completed 500 requests 13 | Completed 600 requests 14 | Completed 700 requests 15 | Completed 800 requests 16 | Completed 900 requests 17 | Completed 1000 requests 18 | Finished 1000 requests 19 | 20 | 21 | Server Software: Apache-Coyote/1.1 22 | Server Hostname: 127.0.0.1 23 | Server Port: 8081 24 | 25 | Document Path: /xultimate-remoting-httpinvoker/accounts 26 | Document Length: 781 bytes 27 | 28 | Concurrency Level: 100 29 | Time taken for tests: 0.363 seconds 30 | Complete requests: 1000 31 | Failed requests: 0 32 | Write errors: 0 33 | Total transferred: 967000 bytes 34 | HTML transferred: 781000 bytes 35 | Requests per second: 2753.62 [#/sec] (mean) 36 | Time per request: 36.316 [ms] (mean) 37 | Time per request: 0.363 [ms] (mean, across all concurrent requests) 38 | Transfer rate: 2600.34 [Kbytes/sec] received 39 | 40 | Connection Times (ms) 41 | min mean[+/-sd] median max 42 | Connect: 0 1 3.3 0 13 43 | Processing: 1 32 24.8 38 154 44 | Waiting: 1 32 24.8 37 154 45 | Total: 1 33 24.7 38 154 46 | 47 | Percentage of the requests served within a certain time (ms) 48 | 50% 38 49 | 66% 40 50 | 75% 42 51 | 80% 43 52 | 90% 68 53 | 95% 80 54 | 98% 100 55 | 99% 115 56 | 100% 154 (longest request) -------------------------------------------------------------------------------- /xultimate-remoting-httpinvoker/src/main/java/org/danielli/xultimate/remoting/web/controller/AccountController.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.web.controller; 2 | 3 | import java.util.List; 4 | 5 | import javax.annotation.Resource; 6 | 7 | import org.danielli.xultimate.remoting.dto.Account; 8 | import org.danielli.xultimate.remoting.service.AccountService; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.ModelMap; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | 14 | @Controller 15 | @RequestMapping("/accounts") 16 | public class AccountController { 17 | 18 | @Resource(name = "remotingHttpInvokerAccountService") 19 | public AccountService accountService; 20 | 21 | @RequestMapping(value = "/add", method = { RequestMethod.GET }) 22 | public String toInsertAccount() { 23 | return "account_add"; 24 | } 25 | 26 | @RequestMapping(method = { RequestMethod.POST }) 27 | public String doInsertAccount(Account account, ModelMap modelMap) { 28 | accountService.insertAccount(account); 29 | modelMap.put("name", account.getName()); 30 | return "redirect:/accounts"; 31 | } 32 | 33 | @RequestMapping(method = { RequestMethod.GET }) 34 | public String getAccounts(Account account, ModelMap modelMap) { 35 | List accountList = null; 36 | if (account == null || account.getName() == null) { 37 | accountList = accountService.getAllAccounts(); 38 | } else { 39 | accountList = accountService.getAccounts(account.getName()); 40 | } 41 | modelMap.put("accounts", accountList); 42 | return "account_list"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /xultimate-remoting-httpinvoker/src/main/resources/applicationContext-service-remoting-httpinvoker.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 36 | 37 | -------------------------------------------------------------------------------- /xultimate-remoting-httpinvoker/src/main/resources/applicationContext-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | import.packages+=org.danielli.xultimate.remoting.dto 38 | template.directory=/WEB-INF/templates/ 39 | input.encoding=UTF-8 40 | output.encoding=UTF-8 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /xultimate-remoting-httpinvoker/src/main/webapp/WEB-INF/templates/account_add.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Add Account 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
18 |
19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-httpinvoker/src/main/webapp/WEB-INF/templates/account_list.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Account List 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
${account.name}
18 | Add Account 19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-httpinvoker/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | isLog4jAutoInitializationDisabled 5 | true 6 | 7 | 8 | 9 | org.apache.logging.log4j.web.Log4jServletContextListener 10 | 11 | 12 | 13 | log4jServletFilter 14 | org.apache.logging.log4j.web.Log4jServletFilter 15 | 16 | 17 | log4jServletFilter 18 | /* 19 | REQUEST 20 | FORWARD 21 | INCLUDE 22 | ERROR 23 | ASYNC 24 | 25 | 26 | 27 | contextConfigLocation 28 | classpath:applicationContext-service.xml, classpath:applicationContext-service-remoting-httpinvoker.xml 29 | 30 | 31 | org.springframework.web.context.ContextLoaderListener 32 | 33 | 34 | 35 | spring 36 | org.springframework.web.servlet.DispatcherServlet 37 | 38 | contextConfigLocation 39 | classpath:applicationContext-servlet.xml 40 | 41 | 42 | 43 | spring 44 | / 45 | 46 | -------------------------------------------------------------------------------- /xultimate-remoting-jms/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.danielli.xultimate 8 | xultimate-remoting 9 | 1.0.0-SNAPSHOT 10 | 11 | 12 | xultimate-remoting-jms 13 | war 14 | 15 | The X-Ultimate Remoting JMS 16 | The X-Ultimate Remoting jms project. 17 | https://github.com/daniellitoc/xultimate-remoting/tree/master/xultimate-remoting-jms 18 | 19 | 20 | 21 | org.apache.activemq 22 | activemq-spring 23 | 5.8.0 24 | 25 | 26 | org.springframework 27 | spring-jms 28 | ${org.springframework.version} 29 | 30 | 31 | 32 | 33 | xultimate-remoting-jms 34 | 35 | 36 | -------------------------------------------------------------------------------- /xultimate-remoting-jms/src/main/java/org/danielli/xultimate/remoting/service/CheckingAccountService.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.service; 2 | 3 | public interface CheckingAccountService { 4 | void cancelAccount(Long accountId); 5 | } 6 | -------------------------------------------------------------------------------- /xultimate-remoting-jms/src/main/java/org/danielli/xultimate/remoting/service/impl/SimpleCheckingAccountService.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.service.impl; 2 | 3 | import org.danielli.xultimate.remoting.service.CheckingAccountService; 4 | import org.springframework.stereotype.Component; 5 | 6 | @Component("simpleCheckingAccountService") 7 | public class SimpleCheckingAccountService implements CheckingAccountService { 8 | 9 | @Override 10 | public void cancelAccount(Long accountId) { 11 | System.out.println("Cancelling account [" + accountId + "]"); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /xultimate-remoting-jms/src/main/java/org/danielli/xultimate/remoting/web/controller/AccountController.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.web.controller; 2 | 3 | import javax.annotation.Resource; 4 | 5 | import org.danielli.xultimate.remoting.service.CheckingAccountService; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.ui.ModelMap; 8 | import org.springframework.web.bind.annotation.PathVariable; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestMethod; 11 | 12 | @Controller 13 | @RequestMapping("/accounts") 14 | public class AccountController { 15 | 16 | @Resource(name = "clientCheckingAccountService") 17 | public CheckingAccountService accountService; 18 | 19 | @RequestMapping(value = "/{accountId}", method = { RequestMethod.GET }) 20 | public String cancelAccount(@PathVariable Long accountId, ModelMap modelMap) { 21 | accountService.cancelAccount(accountId); 22 | return "account_cancel_success"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /xultimate-remoting-jms/src/main/resources/applicationContext-service-remoting-jms-client.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 34 | 35 | -------------------------------------------------------------------------------- /xultimate-remoting-jms/src/main/resources/applicationContext-service-remoting-jms-server.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 35 | 36 | 41 | -------------------------------------------------------------------------------- /xultimate-remoting-jms/src/main/resources/applicationContext-service-remoting-jms-share.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 33 | 35 | 36 | -------------------------------------------------------------------------------- /xultimate-remoting-jms/src/main/resources/applicationContext-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | template.directory=/WEB-INF/templates/ 38 | input.encoding=UTF-8 39 | output.encoding=UTF-8 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /xultimate-remoting-jms/src/main/webapp/WEB-INF/templates/account_cancel_success.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Account Cancel 6 | 7 | 8 |

Success!

9 | 10 | -------------------------------------------------------------------------------- /xultimate-remoting-jms/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | isLog4jAutoInitializationDisabled 5 | true 6 | 7 | 8 | 9 | org.apache.logging.log4j.web.Log4jServletContextListener 10 | 11 | 12 | 13 | log4jServletFilter 14 | org.apache.logging.log4j.web.Log4jServletFilter 15 | 16 | 17 | log4jServletFilter 18 | /* 19 | REQUEST 20 | FORWARD 21 | INCLUDE 22 | ERROR 23 | ASYNC 24 | 25 | 26 | 27 | contextConfigLocation 28 | classpath:applicationContext-service*.xml 29 | 30 | 31 | org.springframework.web.context.ContextLoaderListener 32 | 33 | 34 | 35 | spring 36 | org.springframework.web.servlet.DispatcherServlet 37 | 38 | contextConfigLocation 39 | classpath:applicationContext-servlet.xml 40 | 41 | 42 | 43 | spring 44 | / 45 | 46 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.danielli.xultimate 8 | xultimate-remoting 9 | 1.0.0-SNAPSHOT 10 | 11 | 12 | xultimate-remoting-metaq 13 | war 14 | 15 | The X-Ultimate Remoting MetaQ 16 | The X-Ultimate Remoting metaq project. 17 | https://github.com/daniellitoc/xultimate-remoting/tree/master/xultimate-remoting-metaq 18 | 19 | 20 | 21 | com.taobao.metamorphosis 22 | metamorphosis-client 23 | 1.4.6.2 24 | 25 | 26 | com.taobao.metamorphosis 27 | metamorphosis-client-extension 28 | 1.4.6.2 29 | 30 | 31 | 32 | 33 | xultimate-remoting-metaq 34 | 35 | 36 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/dto/Logging.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.dto; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | public class Logging implements Serializable { 7 | 8 | private static final long serialVersionUID = -4953915789902930882L; 9 | 10 | private String content; 11 | 12 | private Date date; 13 | 14 | 15 | public String getContent() { 16 | return content; 17 | } 18 | 19 | public void setContent(String content) { 20 | this.content = content; 21 | } 22 | 23 | public Date getDate() { 24 | return date; 25 | } 26 | 27 | public void setDate(Date date) { 28 | this.date = date; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/metaq/MessageProducerCallback.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.metaq; 2 | 3 | import com.taobao.metamorphosis.client.extension.spring.MessageBodyConverter; 4 | import com.taobao.metamorphosis.client.producer.MessageProducer; 5 | 6 | /** 7 | * 消息提供器回调。 8 | * 9 | * @author Daniel Li 10 | * @since 15 Jun 2013 11 | */ 12 | public interface MessageProducerCallback { 13 | 14 | void doInMessageProducer(MessageProducer messageProducer, MessageBodyConverter converter, String topic) throws Exception; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/metaq/MessageProducerWithMessageCallback.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.metaq; 2 | 3 | import com.taobao.metamorphosis.Message; 4 | import com.taobao.metamorphosis.client.producer.MessageProducer; 5 | 6 | /** 7 | * 消息提供器回调。 8 | * 9 | * @author Daniel Li 10 | * @since 15 Jun 2013 11 | */ 12 | public interface MessageProducerWithMessageCallback { 13 | 14 | void doInMessageProducer(MessageProducer messageProducer, Message message) throws Exception; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/metaq/MetaqClientException.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.metaq; 2 | 3 | import org.springframework.core.NestedRuntimeException; 4 | 5 | /** 6 | * Metaq消息队列异常类。 7 | * 8 | * @author Daniel Li 9 | * @since 15 Jun 2013 10 | */ 11 | public class MetaqClientException extends NestedRuntimeException { 12 | 13 | private static final long serialVersionUID = 3488287486491666049L; 14 | 15 | public MetaqClientException(String message) { 16 | super(message); 17 | } 18 | 19 | public MetaqClientException(String message, Throwable cause) { 20 | super(message, cause); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/metaq/MetaqTemplateUtils.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.metaq; 2 | 3 | import org.danielli.xultimate.remoting.metaq.support.MetaqTemplate; 4 | 5 | import com.taobao.metamorphosis.Message; 6 | import com.taobao.metamorphosis.client.extension.spring.MessageBodyConverter; 7 | import com.taobao.metamorphosis.client.extension.spring.MessageBuilder; 8 | import com.taobao.metamorphosis.client.producer.MessageProducer; 9 | 10 | /** 11 | * 消息模板工具类。 12 | * 13 | * @author Daniel Li 14 | * @since 15 Jun 2013 15 | */ 16 | public class MetaqTemplateUtils { 17 | 18 | /** 19 | * 发送消息。 20 | * 21 | * @param metaqTemplate 消息模板。 22 | * @param builder 消息构造器。 23 | * @param callback 回调。 24 | * @throws MetaqClientException 回调过程中可能出现的任何异常。 25 | */ 26 | public static void send(MetaqTemplate metaqTemplate, MessageBuilder builder, MessageProducerWithMessageCallback callback) throws MetaqClientException { 27 | Message msg = builder.build(metaqTemplate.getMessageBodyConverter()); 28 | final String topic = msg.getTopic(); 29 | MessageProducer producer = metaqTemplate.getOrCreateProducer(topic); 30 | try { 31 | callback.doInMessageProducer(producer, msg); 32 | } catch (Exception e) { 33 | throw new MetaqClientException(e.getMessage(), e); 34 | } 35 | } 36 | 37 | /** 38 | * 39 | * @param metaqTemplate 消息模板。 40 | * @param topic 消息主题。 41 | * @param callback 回调。 42 | * @throws MetaqClientException 回调过程中可能出现的任何异常。 43 | */ 44 | public static void send(MetaqTemplate metaqTemplate, String topic, MessageProducerCallback callback) throws MetaqClientException { 45 | MessageBodyConverter converter = metaqTemplate.getMessageBodyConverter(); 46 | MessageProducer producer = metaqTemplate.getOrCreateProducer(topic); 47 | try { 48 | callback.doInMessageProducer(producer, converter, topic); 49 | } catch (Exception e) { 50 | throw new MetaqClientException(e.getMessage(), e); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/metaq/support/JavaObjectConverter.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.metaq.support; 2 | 3 | import java.io.IOException; 4 | 5 | import org.danielli.xultimate.core.compression.Compressor; 6 | import org.danielli.xultimate.core.compression.Decompressor; 7 | import org.danielli.xultimate.core.compression.support.NullCompressor; 8 | import org.danielli.xultimate.core.io.support.JavaObjectInput; 9 | import org.danielli.xultimate.core.io.support.JavaObjectOutput; 10 | 11 | import com.taobao.metamorphosis.client.extension.spring.MessageBodyConverter; 12 | import com.taobao.metamorphosis.exception.MetaClientException; 13 | 14 | /** 15 | * 通过{@code JavaObjectInput}和{@code JavaObjectOutput}提供的功能完成序列化/解序列化支持。 16 | * 17 | * @author Daniel Li 18 | * @since 18 Jun 2013 19 | */ 20 | public class JavaObjectConverter implements MessageBodyConverter { 21 | 22 | protected Compressor compressor = NullCompressor.COMPRESSOR; 23 | 24 | protected Decompressor decompressor = NullCompressor.COMPRESSOR; 25 | 26 | protected int bufferSize = 256; 27 | 28 | protected int compressionThreshold = 512; 29 | 30 | public JavaObjectConverter() { 31 | 32 | } 33 | 34 | public JavaObjectConverter(Compressor compressor, Decompressor decompressor) { 35 | this.compressor = compressor; 36 | this.decompressor = decompressor; 37 | } 38 | 39 | /** 设置缓冲大小 */ 40 | public void setBufferSize(int bufferSize) { 41 | this.bufferSize = bufferSize; 42 | } 43 | 44 | /** 设置压缩器 */ 45 | public void setCompressor(Compressor compressor) { 46 | this.compressor = compressor; 47 | } 48 | 49 | /** 设置解压缩器 */ 50 | public void setDecompressor(Decompressor decompressor) { 51 | this.decompressor = decompressor; 52 | } 53 | 54 | /** 设置压缩限度 */ 55 | public void setCompressionThreshold(int compressionThreshold) { 56 | this.compressionThreshold = compressionThreshold; 57 | } 58 | 59 | @Override 60 | public byte[] toByteArray(Object body) throws MetaClientException { 61 | JavaObjectOutput javaObjectOutput = null; 62 | try { 63 | javaObjectOutput = new JavaObjectOutput(bufferSize) ; 64 | javaObjectOutput.writeObject(body); 65 | if (javaObjectOutput.position() > compressionThreshold) { 66 | javaObjectOutput.writeByte(1); 67 | byte[] result = javaObjectOutput.toBytes(); 68 | return compressor.compress(result); 69 | } else { 70 | javaObjectOutput.writeByte(0); 71 | return javaObjectOutput.toBytes(); 72 | } 73 | } catch (IOException e) { 74 | throw new MetaClientException(e.getMessage(), e); 75 | } finally { 76 | javaObjectOutput.close(); 77 | } 78 | // return compressor.compress(rpcSerializer.serialize(body)); 79 | } 80 | 81 | @Override 82 | public Object fromByteArray(byte[] bs) throws MetaClientException { 83 | JavaObjectInput javaObjectInput = null; 84 | try { 85 | if (bs[bs.length - 1] == 0) { 86 | javaObjectInput = new JavaObjectInput(bs, 0, bs.length - 1); 87 | } else { 88 | javaObjectInput = new JavaObjectInput(decompressor.decompress(bs)); 89 | } 90 | return javaObjectInput.readObject(); 91 | } catch (Exception e) { 92 | throw new MetaClientException(e.getMessage(), e); 93 | } finally { 94 | javaObjectInput.close(); 95 | } 96 | // return rpcSerializer.deserialize(decompressor.decompress(bs), Object.class); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/metaq/support/RpcKryoObjectConverter.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.metaq.support; 2 | 3 | import java.io.IOException; 4 | 5 | import org.danielli.xultimate.core.compression.Compressor; 6 | import org.danielli.xultimate.core.compression.Decompressor; 7 | import org.danielli.xultimate.core.compression.support.NullCompressor; 8 | import org.danielli.xultimate.core.io.support.RpcKryoObjectInput; 9 | import org.danielli.xultimate.core.io.support.RpcKryoObjectOutput; 10 | import org.danielli.xultimate.core.serializer.kryo.KryoGenerator; 11 | import org.danielli.xultimate.core.serializer.kryo.support.ThreadLocalKryoGenerator; 12 | 13 | import com.taobao.metamorphosis.client.extension.spring.MessageBodyConverter; 14 | import com.taobao.metamorphosis.exception.MetaClientException; 15 | 16 | /** 17 | * 通过{@code RpcKryoObjectInput}和{@code RpcKryoObjectOutput}提供的功能完成序列化/解序列化支持。 18 | * 19 | * @author Daniel Li 20 | * @since 18 Jun 2013 21 | */ 22 | public class RpcKryoObjectConverter implements MessageBodyConverter { 23 | 24 | protected int bufferSize = 256; 25 | 26 | protected int compressionThreshold = 512; 27 | 28 | protected KryoGenerator kryoGenerator = ThreadLocalKryoGenerator.INSTANCE; 29 | /** 压缩器 */ 30 | protected Compressor compressor = NullCompressor.COMPRESSOR; 31 | /** 解压缩器 */ 32 | protected Decompressor decompressor = NullCompressor.COMPRESSOR; 33 | 34 | public RpcKryoObjectConverter() { 35 | 36 | } 37 | 38 | public RpcKryoObjectConverter(KryoGenerator kryoGenerator, Compressor compressor, Decompressor decompressor) { 39 | this.kryoGenerator = kryoGenerator; 40 | this.compressor = compressor; 41 | this.decompressor = decompressor; 42 | } 43 | 44 | /** 设置缓冲大小 */ 45 | public void setBufferSize(int bufferSize) { 46 | this.bufferSize = bufferSize; 47 | } 48 | 49 | /** 设置压缩器 */ 50 | public void setCompressor(Compressor compressor) { 51 | this.compressor = compressor; 52 | } 53 | 54 | /** 设置解压缩器 */ 55 | public void setDecompressor(Decompressor decompressor) { 56 | this.decompressor = decompressor; 57 | } 58 | 59 | /** 设置压缩限度 */ 60 | public void setCompressionThreshold(int compressionThreshold) { 61 | this.compressionThreshold = compressionThreshold; 62 | } 63 | 64 | @Override 65 | public byte[] toByteArray(Object body) throws MetaClientException { 66 | RpcKryoObjectOutput kryoObjectOutput = new RpcKryoObjectOutput(bufferSize, kryoGenerator.generate()); 67 | try { 68 | kryoObjectOutput.writeObject(body); 69 | if (kryoObjectOutput.position() > compressionThreshold) { 70 | kryoObjectOutput.writeByte(1); 71 | byte[] result = kryoObjectOutput.toBytes(); 72 | return compressor.compress(result); 73 | } else { 74 | kryoObjectOutput.writeByte(0); 75 | return kryoObjectOutput.toBytes(); 76 | } 77 | } catch (IOException e) { 78 | throw new MetaClientException(e.getMessage(), e); 79 | } finally { 80 | kryoObjectOutput.close(); 81 | } 82 | // return compressor.compress(rpcSerializer.serialize(body)); 83 | } 84 | 85 | @Override 86 | public Object fromByteArray(byte[] bs) throws MetaClientException { 87 | RpcKryoObjectInput kryoObjectInput = null; 88 | try { 89 | if (bs[bs.length - 1] == 0) { 90 | kryoObjectInput = new RpcKryoObjectInput(bs, 0, bs.length - 1, kryoGenerator.generate()); 91 | } else { 92 | kryoObjectInput = new RpcKryoObjectInput(decompressor.decompress(bs), kryoGenerator.generate()); 93 | } 94 | return kryoObjectInput.readObject(); 95 | } catch (Exception e) { 96 | throw new MetaClientException(e.getMessage(), e); 97 | } finally { 98 | kryoObjectInput.close(); 99 | } 100 | // return rpcSerializer.deserialize(decompressor.decompress(bs), Object.class); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/metaq/support/RpcProtobufObjectConverter.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.metaq.support; 2 | 3 | import java.io.IOException; 4 | 5 | import org.danielli.xultimate.core.compression.Compressor; 6 | import org.danielli.xultimate.core.compression.Decompressor; 7 | import org.danielli.xultimate.core.compression.support.NullCompressor; 8 | import org.danielli.xultimate.core.io.support.RpcProtobufObjectInput; 9 | import org.danielli.xultimate.core.io.support.RpcProtobufObjectOutput; 10 | import org.danielli.xultimate.core.serializer.kryo.KryoGenerator; 11 | import org.danielli.xultimate.core.serializer.kryo.support.ThreadLocalKryoGenerator; 12 | import org.danielli.xultimate.core.serializer.protostuff.util.LinkedBufferUtils; 13 | 14 | import com.taobao.metamorphosis.client.extension.spring.MessageBodyConverter; 15 | import com.taobao.metamorphosis.exception.MetaClientException; 16 | 17 | /** 18 | * 通过{@code RpcProtobufObjectInput}和{@code RpcProtobufObjectOutput}提供的功能完成序列化/解序列化支持。 19 | * 20 | * @author Daniel Li 21 | * @since 18 Jun 2013 22 | */ 23 | public class RpcProtobufObjectConverter implements MessageBodyConverter { 24 | 25 | protected int bufferSize = 256; 26 | 27 | protected int compressionThreshold = 512; 28 | 29 | protected KryoGenerator kryoGenerator = ThreadLocalKryoGenerator.INSTANCE; 30 | /** 压缩器 */ 31 | protected Compressor compressor = NullCompressor.COMPRESSOR; 32 | /** 解压缩器 */ 33 | protected Decompressor decompressor = NullCompressor.COMPRESSOR; 34 | 35 | public RpcProtobufObjectConverter() { 36 | 37 | } 38 | 39 | public RpcProtobufObjectConverter(KryoGenerator kryoGenerator, Compressor compressor, Decompressor decompressor) { 40 | this.kryoGenerator = kryoGenerator; 41 | this.compressor = compressor; 42 | this.decompressor = decompressor; 43 | } 44 | 45 | /** 设置缓冲大小 */ 46 | public void setBufferSize(int bufferSize) { 47 | this.bufferSize = bufferSize; 48 | } 49 | 50 | /** 设置压缩器 */ 51 | public void setCompressor(Compressor compressor) { 52 | this.compressor = compressor; 53 | } 54 | 55 | /** 设置解压缩器 */ 56 | public void setDecompressor(Decompressor decompressor) { 57 | this.decompressor = decompressor; 58 | } 59 | 60 | /** 设置压缩限度 */ 61 | public void setCompressionThreshold(int compressionThreshold) { 62 | this.compressionThreshold = compressionThreshold; 63 | } 64 | 65 | @Override 66 | public byte[] toByteArray(Object body) throws MetaClientException { 67 | RpcProtobufObjectOutput protobufObjectOutput = new RpcProtobufObjectOutput(bufferSize, LinkedBufferUtils.getCurrentLinkedBuffer(bufferSize), kryoGenerator.generate()) ; 68 | try { 69 | protobufObjectOutput.writeObject(body); 70 | if (protobufObjectOutput.position() > compressionThreshold) { 71 | protobufObjectOutput.writeByte(1); 72 | byte[] result = protobufObjectOutput.toBytes(); 73 | return compressor.compress(result); 74 | } else { 75 | protobufObjectOutput.writeByte(0); 76 | return protobufObjectOutput.toBytes(); 77 | } 78 | } catch (IOException e) { 79 | throw new MetaClientException(e.getMessage(), e); 80 | } finally { 81 | protobufObjectOutput.close(); 82 | } 83 | // return compressor.compress(rpcSerializer.serialize(body)); 84 | } 85 | 86 | @Override 87 | public Object fromByteArray(byte[] bs) throws MetaClientException { 88 | RpcProtobufObjectInput rpcProtobufObjectInput = null; 89 | try { 90 | if (bs[bs.length - 1] == 0) { 91 | rpcProtobufObjectInput = new RpcProtobufObjectInput(bs, 0, bs.length - 1, kryoGenerator.generate()); 92 | } else { 93 | rpcProtobufObjectInput = new RpcProtobufObjectInput(decompressor.decompress(bs), kryoGenerator.generate()); 94 | } 95 | return rpcProtobufObjectInput.readObject(); 96 | } catch (Exception e) { 97 | throw new MetaClientException(e.getMessage(), e); 98 | } finally { 99 | rpcProtobufObjectInput.close(); 100 | } 101 | // return rpcSerializer.deserialize(decompressor.decompress(bs), Object.class); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/metaq/support/RpcProtostuffObjectConverter.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.metaq.support; 2 | 3 | import java.io.IOException; 4 | 5 | import org.danielli.xultimate.core.compression.Compressor; 6 | import org.danielli.xultimate.core.compression.Decompressor; 7 | import org.danielli.xultimate.core.compression.support.NullCompressor; 8 | import org.danielli.xultimate.core.io.support.RpcProtostuffObjectInput; 9 | import org.danielli.xultimate.core.io.support.RpcProtostuffObjectOutput; 10 | import org.danielli.xultimate.core.serializer.kryo.KryoGenerator; 11 | import org.danielli.xultimate.core.serializer.kryo.support.ThreadLocalKryoGenerator; 12 | import org.danielli.xultimate.core.serializer.protostuff.util.LinkedBufferUtils; 13 | 14 | import com.taobao.metamorphosis.client.extension.spring.MessageBodyConverter; 15 | import com.taobao.metamorphosis.exception.MetaClientException; 16 | 17 | /** 18 | * 通过{@code RpcProtostuffObjectInput}和{@code RpcProtostuffObjectOutput}提供的功能完成序列化/解序列化支持。 19 | * 20 | * @author Daniel Li 21 | * @since 18 Jun 2013 22 | */ 23 | public class RpcProtostuffObjectConverter implements MessageBodyConverter { 24 | 25 | protected int bufferSize = 256; 26 | 27 | protected int compressionThreshold = 512; 28 | 29 | protected KryoGenerator kryoGenerator = ThreadLocalKryoGenerator.INSTANCE; 30 | /** 压缩器 */ 31 | protected Compressor compressor = NullCompressor.COMPRESSOR; 32 | /** 解压缩器 */ 33 | protected Decompressor decompressor = NullCompressor.COMPRESSOR; 34 | 35 | public RpcProtostuffObjectConverter() { 36 | 37 | } 38 | 39 | public RpcProtostuffObjectConverter(KryoGenerator kryoGenerator, Compressor compressor, Decompressor decompressor) { 40 | this.kryoGenerator = kryoGenerator; 41 | this.compressor = compressor; 42 | this.decompressor = decompressor; 43 | } 44 | 45 | /** 设置缓冲大小 */ 46 | public void setBufferSize(int bufferSize) { 47 | this.bufferSize = bufferSize; 48 | } 49 | 50 | /** 设置压缩器 */ 51 | public void setCompressor(Compressor compressor) { 52 | this.compressor = compressor; 53 | } 54 | 55 | /** 设置解压缩器 */ 56 | public void setDecompressor(Decompressor decompressor) { 57 | this.decompressor = decompressor; 58 | } 59 | 60 | /** 设置压缩限度 */ 61 | public void setCompressionThreshold(int compressionThreshold) { 62 | this.compressionThreshold = compressionThreshold; 63 | } 64 | 65 | @Override 66 | public byte[] toByteArray(Object body) throws MetaClientException { 67 | RpcProtostuffObjectOutput protostuffObjectOutput = new RpcProtostuffObjectOutput(bufferSize, LinkedBufferUtils.getCurrentLinkedBuffer(bufferSize), kryoGenerator.generate()) ; 68 | try { 69 | protostuffObjectOutput.writeObject(body); 70 | if (protostuffObjectOutput.position() > compressionThreshold) { 71 | protostuffObjectOutput.writeByte(1); 72 | byte[] result = protostuffObjectOutput.toBytes(); 73 | return compressor.compress(result); 74 | } else { 75 | protostuffObjectOutput.writeByte(0); 76 | return protostuffObjectOutput.toBytes(); 77 | } 78 | } catch (IOException e) { 79 | throw new MetaClientException(e.getMessage(), e); 80 | } finally { 81 | protostuffObjectOutput.close(); 82 | } 83 | // return compressor.compress(rpcSerializer.serialize(body)); 84 | } 85 | 86 | @Override 87 | public Object fromByteArray(byte[] bs) throws MetaClientException { 88 | RpcProtostuffObjectInput rpcProtostuffObjectInput = null; 89 | try { 90 | if (bs[bs.length - 1] == 0) { 91 | rpcProtostuffObjectInput = new RpcProtostuffObjectInput(bs, 0, bs.length - 1, kryoGenerator.generate()); 92 | } else { 93 | rpcProtostuffObjectInput = new RpcProtostuffObjectInput(decompressor.decompress(bs), kryoGenerator.generate()); 94 | } 95 | return rpcProtostuffObjectInput.readObject(); 96 | } catch (Exception e) { 97 | throw new MetaClientException(e.getMessage(), e); 98 | } finally { 99 | rpcProtostuffObjectInput.close(); 100 | } 101 | // return rpcSerializer.deserialize(decompressor.decompress(bs), Object.class); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/metaq/support/XMemcachedMessageIdCache.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.metaq.support; 2 | 3 | import org.danielli.xultimate.context.kvStore.memcached.xmemcached.XMemcachedClient; 4 | 5 | import com.taobao.metamorphosis.client.consumer.MessageIdCache; 6 | import com.taobao.metamorphosis.client.consumer.SimpleFetchManager; 7 | 8 | /** 9 | * XMemcached消息ID缓存。 10 | * 11 | * @author Daniel Li 12 | * @since 15 Jun 2013 13 | */ 14 | public class XMemcachedMessageIdCache implements MessageIdCache { 15 | /** XMemcached客户端 */ 16 | private XMemcachedClient xMemcachedClient; 17 | 18 | /** 失效时间 */ 19 | private int expireInSeconds = 60; 20 | 21 | /** 22 | * 设置XMemcached客户端。 23 | * @param xMemcachedClient XMemcached客户端。 24 | */ 25 | public void setxMemcachedClient(XMemcachedClient xMemcachedClient) { 26 | this.xMemcachedClient = xMemcachedClient; 27 | } 28 | /** 29 | * 设置失效时间。 30 | * @param expireInSeconds 失效时间。 31 | */ 32 | public void setExpireInSeconds(int expireInSeconds) { 33 | this.expireInSeconds = expireInSeconds; 34 | } 35 | 36 | @Override 37 | public void put(String key, Byte exists) { 38 | xMemcachedClient.set(key, expireInSeconds, exists); 39 | } 40 | 41 | @Override 42 | public Byte get(final String key) { 43 | return xMemcachedClient.get(key); 44 | } 45 | 46 | /** 47 | * 设置XMemcachedMessageIdCache。 48 | */ 49 | public void addSampleFetchManager() { 50 | SimpleFetchManager.setMessageIdCache(this); 51 | } 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/service/LoggingService.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.service; 2 | 3 | import org.danielli.xultimate.remoting.dto.Logging; 4 | 5 | public interface LoggingService { 6 | 7 | void saveLogging(Logging logging); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/service/impl/LoggingServiceImpl.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.service.impl; 2 | 3 | import org.danielli.xultimate.remoting.dto.Logging; 4 | import org.danielli.xultimate.remoting.service.LoggingService; 5 | import org.springframework.stereotype.Service; 6 | 7 | @Service("loggingServiceImpl") 8 | public class LoggingServiceImpl implements LoggingService { 9 | 10 | @Override 11 | public void saveLogging(Logging logging) { 12 | if (logging == null) { 13 | System.out.println("Logging is null"); 14 | } else { 15 | System.out.println(logging.getDate() + ":" + logging.getContent()); 16 | } 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/service/impl/MetaqClientLoggingService.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.service.impl; 2 | 3 | import javax.annotation.Resource; 4 | 5 | import org.danielli.xultimate.remoting.dto.Logging; 6 | import org.danielli.xultimate.remoting.metaq.MessageProducerCallback; 7 | import org.danielli.xultimate.remoting.metaq.MessageProducerWithMessageCallback; 8 | import org.danielli.xultimate.remoting.metaq.MetaqTemplateUtils; 9 | import org.danielli.xultimate.remoting.metaq.support.MetaqTemplate; 10 | import org.danielli.xultimate.remoting.service.LoggingService; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.stereotype.Service; 14 | 15 | import com.taobao.metamorphosis.Message; 16 | import com.taobao.metamorphosis.client.extension.spring.MessageBodyConverter; 17 | import com.taobao.metamorphosis.client.extension.spring.MessageBuilder; 18 | import com.taobao.metamorphosis.client.producer.MessageProducer; 19 | import com.taobao.metamorphosis.client.producer.SendMessageCallback; 20 | import com.taobao.metamorphosis.client.producer.SendResult; 21 | 22 | @Service("metaqClientLoggingService") 23 | public class MetaqClientLoggingService implements LoggingService { 24 | 25 | @Resource(name = "metaqTemplate") 26 | public MetaqTemplate metaqTemplate; 27 | 28 | public static final String topic = "test"; 29 | 30 | private static final Logger LOGGER = LoggerFactory.getLogger(MetaqClientLoggingService.class); 31 | 32 | @Override 33 | public void saveLogging(Logging logging) { 34 | MetaqTemplateUtils.send(metaqTemplate, MessageBuilder.withTopic(topic).withBody(logging), new MessageProducerWithMessageCallback() { 35 | 36 | @Override 37 | public void doInMessageProducer(MessageProducer messageProducer, Message message) throws Exception { 38 | SendResult sendResult = messageProducer.sendMessage(message); 39 | if (!sendResult.isSuccess()) { 40 | LOGGER.error("Send message failed,error message:" + sendResult.getErrorMessage()); 41 | } else { 42 | LOGGER.info("Send message successfully,sent to " + sendResult.getPartition()); 43 | } 44 | } 45 | }); 46 | 47 | MetaqTemplateUtils.send(metaqTemplate, MessageBuilder.withTopic(topic).withBody(logging), new MessageProducerWithMessageCallback() { 48 | 49 | @Override 50 | public void doInMessageProducer(MessageProducer messageProducer, Message message) throws Exception { 51 | messageProducer.sendMessage(message, new SendMessageCallback() { 52 | 53 | @Override 54 | public void onMessageSent(SendResult result) { 55 | if (!result.isSuccess()) { 56 | LOGGER.error("Send message failed,error message:" + result.getErrorMessage()); 57 | } else { 58 | LOGGER.info("Send message successfully,sent to " + result.getPartition()); 59 | } 60 | } 61 | 62 | @Override 63 | public void onException(Throwable e) { 64 | LOGGER.error("Send message failed", e); 65 | } 66 | }); 67 | } 68 | }); 69 | 70 | final Logging transactionLogging = logging; 71 | MetaqTemplateUtils.send(metaqTemplate, topic, new MessageProducerCallback() { 72 | 73 | @Override 74 | public void doInMessageProducer(MessageProducer messageProducer, MessageBodyConverter converter, String topic) throws Exception { 75 | messageProducer.setTransactionTimeout(10); 76 | try { 77 | // 开始事务 78 | messageProducer.beginTransaction(); 79 | // 在事务内发送两条消息 80 | if (!messageProducer.sendMessage(new Message(topic, converter.toByteArray(transactionLogging))).isSuccess()) { 81 | // 发送失败,立即回滚 82 | messageProducer.rollback(); 83 | } 84 | if (!messageProducer.sendMessage(new Message(topic, converter.toByteArray(transactionLogging))).isSuccess()) { 85 | messageProducer.rollback(); 86 | } 87 | // 提交 88 | messageProducer.commit(); 89 | } catch (final Exception e) { 90 | messageProducer.rollback(); 91 | throw e; 92 | } 93 | } 94 | }); 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/service/impl/MetaqLoggingMessageListener.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.service.impl; 2 | 3 | import javax.annotation.Resource; 4 | 5 | import org.danielli.xultimate.remoting.dto.Logging; 6 | import org.danielli.xultimate.remoting.service.LoggingService; 7 | 8 | import com.taobao.metamorphosis.client.extension.spring.DefaultMessageListener; 9 | import com.taobao.metamorphosis.client.extension.spring.MetaqMessage; 10 | 11 | public class MetaqLoggingMessageListener extends DefaultMessageListener { 12 | 13 | @Resource(name= "loggingServiceImpl") 14 | private LoggingService loggingService; 15 | 16 | @Override 17 | public void onReceiveMessages(MetaqMessage msg) { 18 | // msg.getPartition().setAutoAck(false); 19 | loggingService.saveLogging(msg.getBody()); 20 | // msg.getPartition().ack(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/java/org/danielli/xultimate/remoting/web/controller/LoggingController.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.web.controller; 2 | 3 | import httl.util.StringUtils; 4 | 5 | import java.util.Date; 6 | 7 | import javax.annotation.Resource; 8 | 9 | import org.danielli.xultimate.remoting.dto.Logging; 10 | import org.danielli.xultimate.remoting.service.LoggingService; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.ui.ModelMap; 13 | import org.springframework.web.bind.annotation.RequestMapping; 14 | import org.springframework.web.bind.annotation.RequestMethod; 15 | import org.springframework.web.bind.annotation.RequestParam; 16 | 17 | @Controller 18 | @RequestMapping("/logging") 19 | public class LoggingController { 20 | 21 | @Resource(name = "metaqClientLoggingService") 22 | public LoggingService loggingService; 23 | 24 | @RequestMapping(method = { RequestMethod.GET }) 25 | public String saveLogging(@RequestParam(required = false) String content, ModelMap modelMap) { 26 | if (!StringUtils.isEmpty(content)) { 27 | Logging logging = new Logging(); 28 | logging.setContent(content); 29 | logging.setDate(new Date()); 30 | loggingService.saveLogging(logging); 31 | } else { 32 | loggingService.saveLogging(null); 33 | } 34 | return "logging_save_success"; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/resources/applicationContext-service-memcached.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 1 42 | 48 | 49 | 50 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/resources/applicationContext-service-remoting-metaq-client.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/resources/applicationContext-service-remoting-metaq-server.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/resources/applicationContext-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | import.packages+=org.danielli.xultimate.remoting.dto 38 | template.directory=/WEB-INF/templates/ 39 | input.encoding=UTF-8 40 | output.encoding=UTF-8 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/resources/meta_log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.logger.testLog=info, testMessage 2 | log4j.additivity.testMessage=false 3 | log4j.appender.testMessage=com.taobao.metamorphosis.client.extension.log4j.DailyRollingFileStreamAppender 4 | log4j.appender.testMessage.topic=meta-test 5 | log4j.appender.testMessage.zkConnect=127.0.0.1:2181 6 | log4j.appender.testMessage.BufferedIO=true 7 | log4j.appender.testMessage.DatePattern='.'yyyy-MM-dd_HH 8 | log4j.appender.testMessage.File=../../logs/test.log 9 | log4j.appender.testMessage.layout=org.apache.log4j.PatternLayout 10 | log4j.appender.testMessage.layout.ConversionPattern=%d{MM-dd HH:mm:ss} - %m%n 11 | log4j.appender.testMessage.Append=true -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/webapp/WEB-INF/templates/logging_save_success.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Account Cancel 6 | 7 | 8 |

Success!

9 | 10 | -------------------------------------------------------------------------------- /xultimate-remoting-metaq/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | isLog4jAutoInitializationDisabled 5 | true 6 | 7 | 8 | 9 | org.apache.logging.log4j.web.Log4jServletContextListener 10 | 11 | 12 | 13 | log4jServletFilter 14 | org.apache.logging.log4j.web.Log4jServletFilter 15 | 16 | 17 | log4jServletFilter 18 | /* 19 | REQUEST 20 | FORWARD 21 | INCLUDE 22 | ERROR 23 | ASYNC 24 | 25 | 26 | 27 | contextConfigLocation 28 | classpath:applicationContext-service*.xml 29 | 30 | 31 | org.springframework.web.context.ContextLoaderListener 32 | 33 | 34 | 35 | spring 36 | org.springframework.web.servlet.DispatcherServlet 37 | 38 | contextConfigLocation 39 | classpath:applicationContext-servlet.xml 40 | 41 | 42 | 43 | spring 44 | / 45 | 46 | -------------------------------------------------------------------------------- /xultimate-remoting-rest/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.danielli.xultimate 8 | xultimate-remoting 9 | 1.0.0-SNAPSHOT 10 | 11 | 12 | xultimate-remoting-rest 13 | 14 | war 15 | 16 | The X-Ultimate Remoting REST 17 | The X-Ultimate Remoting rest project. 18 | https://github.com/daniellitoc/xultimate-remoting/tree/master/xultimate-remoting-rest 19 | 20 | 21 | 22 | ${project.groupId} 23 | xultimate-remoting-service 24 | ${project.version} 25 | 26 | 27 | 28 | 29 | xultimate-remoting-rest 30 | 31 | 32 | -------------------------------------------------------------------------------- /xultimate-remoting-rest/result.txt: -------------------------------------------------------------------------------- 1 | 测试过程中出现异常。 2 | ab -c 100 -n 1000 http://127.0.0.1:8081/xultimate-remoting-rest/accounts 3 | 4 | This is ApacheBench, Version 2.3 <$Revision: 655654 $> 5 | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 6 | Licensed to The Apache Software Foundation, http://www.apache.org/ 7 | 8 | Benchmarking 127.0.0.1 (be patient) 9 | Completed 100 requests 10 | Completed 200 requests 11 | Completed 300 requests 12 | Completed 400 requests 13 | Completed 500 requests 14 | Completed 600 requests 15 | Completed 700 requests 16 | Completed 800 requests 17 | Completed 900 requests 18 | Completed 1000 requests 19 | Finished 1000 requests 20 | 21 | 22 | Server Software: Apache-Coyote/1.1 23 | Server Hostname: 127.0.0.1 24 | Server Port: 8081 25 | 26 | Document Path: /xultimate-remoting-rest/accounts 27 | Document Length: 774 bytes 28 | 29 | Concurrency Level: 100 30 | Time taken for tests: 0.308 seconds 31 | Complete requests: 1000 32 | Failed requests: 0 33 | Write errors: 0 34 | Total transferred: 960000 bytes 35 | HTML transferred: 774000 bytes 36 | Requests per second: 3248.76 [#/sec] (mean) 37 | Time per request: 30.781 [ms] (mean) 38 | Time per request: 0.308 [ms] (mean, across all concurrent requests) 39 | Transfer rate: 3045.71 [Kbytes/sec] received 40 | 41 | Connection Times (ms) 42 | min mean[+/-sd] median max 43 | Connect: 0 1 1.9 0 8 44 | Processing: 6 28 11.0 27 67 45 | Waiting: 5 28 11.1 26 67 46 | Total: 10 29 10.4 27 67 47 | 48 | Percentage of the requests served within a certain time (ms) 49 | 50% 27 50 | 66% 34 51 | 75% 37 52 | 80% 39 53 | 90% 43 54 | 95% 47 55 | 98% 52 56 | 99% 54 57 | 100% 67 (longest request) -------------------------------------------------------------------------------- /xultimate-remoting-rest/src/main/java/org/danielli/xultimate/remoting/controller/web/AccountController.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.controller.web; 2 | 3 | import java.util.List; 4 | 5 | import javax.annotation.Resource; 6 | 7 | import org.danielli.xultimate.remoting.dto.Account; 8 | import org.danielli.xultimate.remoting.service.AccountService; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.ModelMap; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | 14 | @Controller 15 | @RequestMapping("/accounts") 16 | public class AccountController { 17 | 18 | @Resource(name = "remoteAccountService") 19 | public AccountService accountService; 20 | 21 | @RequestMapping(value = "/add", method = { RequestMethod.GET }) 22 | public String toInsertAccount() { 23 | return "account_add"; 24 | } 25 | 26 | @RequestMapping(method = { RequestMethod.POST }) 27 | public String doInsertAccount(Account account, ModelMap modelMap) { 28 | accountService.insertAccount(account); 29 | modelMap.put("name", account.getName()); 30 | return "redirect:/accounts"; 31 | } 32 | 33 | @RequestMapping(method = { RequestMethod.GET }) 34 | public String getAccounts(Account account, ModelMap modelMap) { 35 | List accountList = null; 36 | if (account == null || account.getName() == null) { 37 | accountList = accountService.getAllAccounts(); 38 | } else { 39 | accountList = accountService.getAccounts(account.getName()); 40 | } 41 | modelMap.put("accounts", accountList); 42 | return "account_list"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /xultimate-remoting-rest/src/main/java/org/danielli/xultimate/remoting/controller/web/RemoteAccountController.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.controller.web; 2 | 3 | import java.util.List; 4 | 5 | import javax.annotation.Resource; 6 | 7 | import org.danielli.xultimate.remoting.dto.Account; 8 | import org.danielli.xultimate.remoting.service.AccountService; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.web.bind.annotation.RequestBody; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | import org.springframework.web.bind.annotation.ResponseBody; 14 | 15 | @Controller 16 | @RequestMapping("/remoting/accounts") 17 | public class RemoteAccountController { 18 | 19 | @Resource(name = "accountService") 20 | public AccountService accountService; 21 | 22 | @RequestMapping(method = { RequestMethod.POST }) 23 | @ResponseBody 24 | public Account doInsertAccount(@RequestBody Account account) { 25 | accountService.insertAccount(account); 26 | return account; 27 | } 28 | 29 | @RequestMapping(method = { RequestMethod.GET }) 30 | @ResponseBody 31 | public List getAccounts(Account account) { 32 | if (account == null || account.getName() == null) { 33 | return accountService.getAllAccounts(); 34 | } else { 35 | return accountService.getAccounts(account.getName()); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /xultimate-remoting-rest/src/main/java/org/danielli/xultimate/remoting/service/impl/RemoteAccountService.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.service.impl; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.Collections; 6 | import java.util.List; 7 | 8 | import javax.annotation.Resource; 9 | 10 | import org.danielli.xultimate.remoting.dto.Account; 11 | import org.danielli.xultimate.remoting.service.AccountService; 12 | import org.springframework.http.HttpEntity; 13 | import org.springframework.http.HttpHeaders; 14 | import org.springframework.http.HttpMethod; 15 | import org.springframework.http.MediaType; 16 | import org.springframework.http.ResponseEntity; 17 | import org.springframework.stereotype.Service; 18 | import org.springframework.util.Assert; 19 | import org.springframework.web.client.RestTemplate; 20 | 21 | @Service("remoteAccountService") 22 | public class RemoteAccountService implements AccountService { 23 | 24 | @Resource(name = "restTemplate") 25 | private RestTemplate restTemplate; 26 | 27 | private HttpHeaders getHttpHeaders() { 28 | HttpHeaders entityHeaders = new HttpHeaders(); 29 | entityHeaders.setContentType(MediaType.valueOf("application/json;UTF-8")); 30 | entityHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); 31 | return entityHeaders; 32 | } 33 | 34 | 35 | @Override 36 | public void insertAccount(Account account) { 37 | HttpEntity httpEntity = new HttpEntity(account, getHttpHeaders()); 38 | ResponseEntity responseEntity = restTemplate.exchange("http://localhost:8082/xultimate-remoting-rest/remoting/accounts", HttpMethod.POST, httpEntity, Account.class); 39 | Assert.isTrue(account.getName().equals(responseEntity.getBody().getName())); 40 | } 41 | 42 | @Override 43 | public List getAccounts(String name) { 44 | HttpEntity httpEntity = new HttpEntity<>(getHttpHeaders()); 45 | ResponseEntity entity = restTemplate.exchange("http://localhost:8082/xultimate-remoting-rest/remoting/accounts?name={name}", HttpMethod.GET, httpEntity, Account[].class, name); 46 | if (entity.getBody() == null) 47 | return new ArrayList<>(0); 48 | return Arrays.asList(entity.getBody()); 49 | } 50 | 51 | @Override 52 | public List getAllAccounts() { 53 | HttpEntity httpEntity = new HttpEntity<>(getHttpHeaders()); 54 | ResponseEntity entity = restTemplate.exchange("http://localhost:8082/xultimate-remoting-rest/remoting/accounts", HttpMethod.GET, httpEntity, Account[].class); 55 | if (entity.getBody() == null) 56 | return new ArrayList<>(0); 57 | return Arrays.asList(entity.getBody()); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /xultimate-remoting-rest/src/main/resources/applicationContext-service-remoting-rest.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /xultimate-remoting-rest/src/main/resources/applicationContext-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | import.packages+=org.danielli.xultimate.remoting.dto 46 | template.directory=/WEB-INF/templates/ 47 | input.encoding=UTF-8 48 | output.encoding=UTF-8 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /xultimate-remoting-rest/src/main/webapp/WEB-INF/templates/account_add.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Add Account 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
18 |
19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-rest/src/main/webapp/WEB-INF/templates/account_list.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Account List 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
${account.name}
18 | Add Account 19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-rest/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | isLog4jAutoInitializationDisabled 5 | true 6 | 7 | 8 | 9 | org.apache.logging.log4j.web.Log4jServletContextListener 10 | 11 | 12 | 13 | log4jServletFilter 14 | org.apache.logging.log4j.web.Log4jServletFilter 15 | 16 | 17 | log4jServletFilter 18 | /* 19 | REQUEST 20 | FORWARD 21 | INCLUDE 22 | ERROR 23 | ASYNC 24 | 25 | 26 | 27 | contextConfigLocation 28 | classpath:applicationContext-service.xml, classpath:applicationContext-service-remoting-rest.xml 29 | 30 | 31 | org.springframework.web.context.ContextLoaderListener 32 | 33 | 34 | 35 | spring 36 | org.springframework.web.servlet.DispatcherServlet 37 | 38 | contextConfigLocation 39 | classpath:applicationContext-servlet.xml 40 | 41 | 42 | 43 | spring 44 | / 45 | 46 | -------------------------------------------------------------------------------- /xultimate-remoting-rmi/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.danielli.xultimate 8 | xultimate-remoting 9 | 1.0.0-SNAPSHOT 10 | 11 | 12 | xultimate-remoting-rmi 13 | 14 | war 15 | 16 | The X-Ultimate Remoting RMI 17 | The X-Ultimate Remoting rmi project. 18 | https://github.com/daniellitoc/xultimate-remoting/tree/master/xultimate-remoting-rmi 19 | 20 | 21 | 22 | ${project.groupId} 23 | xultimate-remoting-service 24 | ${project.version} 25 | 26 | 27 | 28 | 29 | xultimate-remoting-rmi 30 | 31 | 32 | -------------------------------------------------------------------------------- /xultimate-remoting-rmi/result.txt: -------------------------------------------------------------------------------- 1 | ab -c 100 -n 1000 http://127.0.0.1:8081/xultimate-remoting-rmi/accounts 2 | 3 | This is ApacheBench, Version 2.3 <$Revision: 655654 $> 4 | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 5 | Licensed to The Apache Software Foundation, http://www.apache.org/ 6 | 7 | Benchmarking 127.0.0.1 (be patient) 8 | Completed 100 requests 9 | Completed 200 requests 10 | Completed 300 requests 11 | Completed 400 requests 12 | Completed 500 requests 13 | Completed 600 requests 14 | Completed 700 requests 15 | Completed 800 requests 16 | Completed 900 requests 17 | Completed 1000 requests 18 | Finished 1000 requests 19 | 20 | 21 | Server Software: Apache-Coyote/1.1 22 | Server Hostname: 127.0.0.1 23 | Server Port: 8081 24 | 25 | Document Path: /xultimate-remoting-rmi/accounts 26 | Document Length: 803 bytes 27 | 28 | Concurrency Level: 100 29 | Time taken for tests: 0.209 seconds 30 | Complete requests: 1000 31 | Failed requests: 0 32 | Write errors: 0 33 | Total transferred: 989000 bytes 34 | HTML transferred: 803000 bytes 35 | Requests per second: 4784.99 [#/sec] (mean) 36 | Time per request: 20.899 [ms] (mean) 37 | Time per request: 0.209 [ms] (mean, across all concurrent requests) 38 | Transfer rate: 4621.44 [Kbytes/sec] received 39 | 40 | Connection Times (ms) 41 | min mean[+/-sd] median max 42 | Connect: 0 1 2.3 0 10 43 | Processing: 4 19 6.5 18 59 44 | Waiting: 1 19 6.6 18 59 45 | Total: 9 20 5.9 18 59 46 | 47 | Percentage of the requests served within a certain time (ms) 48 | 50% 18 49 | 66% 20 50 | 75% 21 51 | 80% 22 52 | 90% 26 53 | 95% 32 54 | 98% 38 55 | 99% 41 56 | 100% 59 (longest request) -------------------------------------------------------------------------------- /xultimate-remoting-rmi/src/main/java/org/danielli/xultimate/remoting/web/controller/AccountController.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.web.controller; 2 | 3 | import java.util.List; 4 | 5 | import javax.annotation.Resource; 6 | 7 | import org.danielli.xultimate.remoting.dto.Account; 8 | import org.danielli.xultimate.remoting.service.AccountService; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.ModelMap; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestMethod; 13 | 14 | @Controller 15 | @RequestMapping("/accounts") 16 | public class AccountController { 17 | 18 | @Resource(name = "remotingRrmiAccountService") 19 | public AccountService accountService; 20 | 21 | @RequestMapping(value = "/add", method = { RequestMethod.GET }) 22 | public String toInsertAccount() { 23 | return "account_add"; 24 | } 25 | 26 | @RequestMapping(method = { RequestMethod.POST }) 27 | public String doInsertAccount(Account account, ModelMap modelMap) { 28 | accountService.insertAccount(account); 29 | modelMap.put("name", account.getName()); 30 | return "redirect:/accounts"; 31 | } 32 | 33 | @RequestMapping(method = { RequestMethod.GET }) 34 | public String getAccounts(Account account, ModelMap modelMap) { 35 | List accountList = null; 36 | if (account == null || account.getName() == null) { 37 | accountList = accountService.getAllAccounts(); 38 | } else { 39 | accountList = accountService.getAccounts(account.getName()); 40 | } 41 | modelMap.put("accounts", accountList); 42 | return "account_list"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /xultimate-remoting-rmi/src/main/resources/applicationContext-service-remoting-rmi.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /xultimate-remoting-rmi/src/main/resources/applicationContext-servlet.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | import.packages+=org.danielli.xultimate.remoting.dto 38 | template.directory=/WEB-INF/templates/ 39 | input.encoding=UTF-8 40 | output.encoding=UTF-8 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /xultimate-remoting-rmi/src/main/webapp/WEB-INF/templates/account_add.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Add Account 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
18 |
19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-rmi/src/main/webapp/WEB-INF/templates/account_list.httl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Account List 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
Name
${account.name}
18 | Add Account 19 | 20 | -------------------------------------------------------------------------------- /xultimate-remoting-rmi/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | isLog4jAutoInitializationDisabled 5 | true 6 | 7 | 8 | 9 | org.apache.logging.log4j.web.Log4jServletContextListener 10 | 11 | 12 | 13 | log4jServletFilter 14 | org.apache.logging.log4j.web.Log4jServletFilter 15 | 16 | 17 | log4jServletFilter 18 | /* 19 | REQUEST 20 | FORWARD 21 | INCLUDE 22 | ERROR 23 | ASYNC 24 | 25 | 26 | 27 | contextConfigLocation 28 | classpath:applicationContext-service.xml, classpath:applicationContext-service-remoting-rmi.xml 29 | 30 | 31 | org.springframework.web.context.ContextLoaderListener 32 | 33 | 34 | 35 | spring 36 | org.springframework.web.servlet.DispatcherServlet 37 | 38 | contextConfigLocation 39 | classpath:applicationContext-servlet.xml 40 | 41 | 42 | 43 | spring 44 | / 45 | 46 | -------------------------------------------------------------------------------- /xultimate-remoting-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | org.danielli.xultimate 9 | xultimate-remoting 10 | 1.0.0-SNAPSHOT 11 | 12 | 13 | xultimate-remoting-service 14 | 15 | The X-Ultimate Remoting Service 16 | The X-Ultimate Remoting service project. 17 | https://github.com/daniellitoc/xultimate-remoting/tree/master/xultimate-remoting-service 18 | 19 | -------------------------------------------------------------------------------- /xultimate-remoting-service/src/main/java/org/danielli/xultimate/remoting/dto/Account.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.dto; 2 | 3 | import java.io.Serializable; 4 | 5 | public class Account implements Serializable { 6 | 7 | private static final long serialVersionUID = 2718159871145819262L; 8 | 9 | private String name; 10 | 11 | public String getName() { 12 | return name; 13 | } 14 | 15 | public void setName(String name) { 16 | this.name = name; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /xultimate-remoting-service/src/main/java/org/danielli/xultimate/remoting/service/AccountService.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.service; 2 | 3 | import java.util.List; 4 | 5 | import org.danielli.xultimate.remoting.dto.Account; 6 | 7 | public interface AccountService { 8 | void insertAccount(Account account); 9 | 10 | List getAccounts(String name); 11 | 12 | List getAllAccounts(); 13 | } 14 | -------------------------------------------------------------------------------- /xultimate-remoting-service/src/main/java/org/danielli/xultimate/remoting/service/impl/AccountServiceImpl.java: -------------------------------------------------------------------------------- 1 | package org.danielli.xultimate.remoting.service.impl; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.concurrent.ConcurrentHashMap; 7 | 8 | import org.danielli.xultimate.remoting.dto.Account; 9 | import org.danielli.xultimate.remoting.service.AccountService; 10 | import org.springframework.stereotype.Component; 11 | 12 | @Component("accountService") 13 | public class AccountServiceImpl implements AccountService { 14 | 15 | private Map> accountMap = new ConcurrentHashMap>(); 16 | 17 | @Override 18 | public void insertAccount(Account account) { 19 | String name = account.getName(); 20 | synchronized (accountMap) { 21 | List accountList = accountMap.get(name); 22 | if (accountList == null) { 23 | accountList = new ArrayList<>(); 24 | accountMap.put(name, accountList); 25 | } 26 | accountList.add(account); 27 | } 28 | 29 | 30 | } 31 | 32 | @Override 33 | public List getAccounts(String name) { 34 | return accountMap.get(name); 35 | } 36 | 37 | @Override 38 | public List getAllAccounts() { 39 | List allAccounts = new ArrayList<>(); 40 | synchronized (accountMap) { 41 | for (List accounts : accountMap.values()) { 42 | allAccounts.addAll(accounts); 43 | } 44 | } 45 | return allAccounts; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /xultimate-remoting-service/src/main/resources/applicationContext-service.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 31 | 32 | --------------------------------------------------------------------------------