├── .idea ├── compiler.xml ├── libraries │ ├── Maven__aopalliance_aopalliance_1_0.xml │ ├── Maven__com_dyuproject_protostuff_protostuff_api_1_0_10.xml │ ├── Maven__com_dyuproject_protostuff_protostuff_collectionschema_1_0_10.xml │ ├── Maven__com_dyuproject_protostuff_protostuff_core_1_0_10.xml │ ├── Maven__com_dyuproject_protostuff_protostuff_runtime_1_0_10.xml │ ├── Maven__com_github_sgroschupf_zkclient_0_1.xml │ ├── Maven__commons_logging_commons_logging_1_2.xml │ ├── Maven__io_netty_netty_3_7_0_Final.xml │ ├── Maven__io_netty_netty_all_4_1_14_Final.xml │ ├── Maven__jline_jline_0_9_94.xml │ ├── Maven__junit_junit_4_12.xml │ ├── Maven__log4j_log4j_1_2_16.xml │ ├── Maven__org_apache_zookeeper_zookeeper_3_4_6.xml │ ├── Maven__org_hamcrest_hamcrest_core_1_3.xml │ ├── Maven__org_slf4j_slf4j_api_1_6_1.xml │ ├── Maven__org_slf4j_slf4j_log4j12_1_6_1.xml │ ├── Maven__org_springframework_spring_aop_4_1_7_RELEASE.xml │ ├── Maven__org_springframework_spring_beans_4_1_7_RELEASE.xml │ ├── Maven__org_springframework_spring_context_4_1_7_RELEASE.xml │ ├── Maven__org_springframework_spring_core_4_1_7_RELEASE.xml │ ├── Maven__org_springframework_spring_expression_4_1_7_RELEASE.xml │ └── Maven__org_springframework_spring_test_4_1_7_RELEASE.xml ├── misc.xml ├── modules.xml ├── uiDesigner.xml └── vcs.xml ├── README.md ├── my-rpc.iml ├── pom.xml ├── rpc-consumer ├── pom.xml ├── rpc-consumer.iml └── src │ └── main │ ├── java │ └── top │ │ └── yuyufeng │ │ └── rpc │ │ └── test │ │ ├── ClientApp.java │ │ └── ClientAppSpring.java │ └── resources │ └── my-rpc-consumer.xml ├── rpc-core ├── pom.xml ├── rpc-core.iml └── src │ └── main │ └── java │ └── top │ └── yuyufeng │ └── rpc │ ├── MyDecoder.java │ ├── MyEncoder.java │ ├── RpcRequest.java │ ├── RpcResponse.java │ ├── client │ ├── ClientCluster.java │ ├── DiscoverService.java │ ├── MyClientHandler.java │ ├── MyNettyClient.java │ ├── proxy │ │ ├── ProxyHandler.java │ │ └── RemoteServiceImpl.java │ └── spring │ │ └── MyRpcReference.java │ ├── exception │ └── RpcException.java │ ├── server │ ├── MyServer.java │ ├── MyServerHandler.java │ ├── RegisterServicesCenter.java │ ├── RpcServer.java │ ├── RpcServerImpl.java │ └── spring │ │ ├── MyRpcConfig.java │ │ └── RpcServerFactory.java │ └── utils │ └── ProtostuffUtil.java ├── rpc-provider ├── pom.xml ├── rpc-provider.iml └── src │ └── main │ ├── java │ └── top │ │ └── yuyufeng │ │ └── rpc │ │ ├── ServerApp.java │ │ ├── ServerAppBySpring.java │ │ └── service │ │ └── impl │ │ ├── CalServiceImpl.java │ │ └── HelloServiceImpl.java │ └── resources │ └── my-rpc-provider.xml └── rpc-service ├── pom.xml ├── rpc-service.iml └── src └── main └── java └── top └── yuyufeng └── rpc └── service ├── CalService.java ├── HelloService.java └── top └── yuyufeng └── dto └── MyResult.java /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_dyuproject_protostuff_protostuff_api_1_0_10.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_dyuproject_protostuff_protostuff_collectionschema_1_0_10.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_dyuproject_protostuff_protostuff_core_1_0_10.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_dyuproject_protostuff_protostuff_runtime_1_0_10.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__com_github_sgroschupf_zkclient_0_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__commons_logging_commons_logging_1_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__io_netty_netty_3_7_0_Final.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__io_netty_netty_all_4_1_14_Final.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__jline_jline_0_9_94.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__junit_junit_4_12.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__log4j_log4j_1_2_16.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_apache_zookeeper_zookeeper_3_4_6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_slf4j_slf4j_api_1_6_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_slf4j_slf4j_log4j12_1_6_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_aop_4_1_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_beans_4_1_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_context_4_1_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_core_4_1_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_expression_4_1_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__org_springframework_spring_test_4_1_7_RELEASE.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | false 5 | 6 | false 7 | false 8 | 9 | 10 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Abstraction issuesJava 25 | 26 | 27 | Android 28 | 29 | 30 | Android > Lint > Accessibility 31 | 32 | 33 | Android > Lint > Correctness 34 | 35 | 36 | Android > Lint > Correctness > Messages 37 | 38 | 39 | Android > Lint > Internationalization 40 | 41 | 42 | Android > Lint > Internationalization > Bidirectional Text 43 | 44 | 45 | Android > Lint > Performance 46 | 47 | 48 | Android > Lint > Security 49 | 50 | 51 | Android > Lint > Usability 52 | 53 | 54 | Android > Lint > Usability > Icons 55 | 56 | 57 | Android Lint for Kotlin 58 | 59 | 60 | Assignment issuesGroovy 61 | 62 | 63 | Assignment issuesJava 64 | 65 | 66 | Bitwise operation issuesJava 67 | 68 | 69 | Bitwise operation issuesJavaScript 70 | 71 | 72 | CDI(Contexts and Dependency Injection) issues 73 | 74 | 75 | CSS 76 | 77 | 78 | Class metricsJava 79 | 80 | 81 | Class structureJava 82 | 83 | 84 | Cloning issuesJava 85 | 86 | 87 | Code maturity issuesJava 88 | 89 | 90 | Code style issuesJava 91 | 92 | 93 | Code style issuesJavaScript 94 | 95 | 96 | CodeSpring CoreSpring 97 | 98 | 99 | Compiler issuesJava 100 | 101 | 102 | Control flow issuesJava 103 | 104 | 105 | Control flow issuesJavaScript 106 | 107 | 108 | DOM issuesJavaScript 109 | 110 | 111 | Data flow issuesJava 112 | 113 | 114 | Data flow issuesJavaScript 115 | 116 | 117 | ECMAScript 6 migration aidsJavaScript 118 | 119 | 120 | Encapsulation issuesJava 121 | 122 | 123 | Error handlingGroovy 124 | 125 | 126 | Error handlingJava 127 | 128 | 129 | Error handlingJavaScript 130 | 131 | 132 | Finalization issuesJava 133 | 134 | 135 | General 136 | 137 | 138 | GeneralJavaScript 139 | 140 | 141 | Google Web Toolkit issues 142 | 143 | 144 | Groovy 145 | 146 | 147 | Guice Inspections 148 | 149 | 150 | HTML 151 | 152 | 153 | ImportsJava 154 | 155 | 156 | Inheritance issuesJava 157 | 158 | 159 | Initialization issuesJava 160 | 161 | 162 | Internationalization issuesJava 163 | 164 | 165 | J2ME issuesJava 166 | 167 | 168 | JBoss Seam issues 169 | 170 | 171 | JSON 172 | 173 | 174 | JSP Inspections 175 | 176 | 177 | JUnit issuesJava 178 | 179 | 180 | Java 181 | 182 | 183 | Java EE issues 184 | 185 | 186 | Java language level migration aidsJava 187 | 188 | 189 | JavaBeans issuesJava 190 | 191 | 192 | JavaFX 193 | 194 | 195 | JavaScript 196 | 197 | 198 | JavaScript function metricsJavaScript 199 | 200 | 201 | Javadoc issuesJava 202 | 203 | 204 | Kotlin 205 | 206 | 207 | Logging issuesJava 208 | 209 | 210 | Memory issuesJava 211 | 212 | 213 | Method MetricsGroovy 214 | 215 | 216 | Method metricsJava 217 | 218 | 219 | Naming conventionsJava 220 | 221 | 222 | Numeric issuesJava 223 | 224 | 225 | OtherGroovy 226 | 227 | 228 | Performance issuesJava 229 | 230 | 231 | Plugin DevKit 232 | 233 | 234 | Portability issuesJava 235 | 236 | 237 | Potentially confusing code constructsGroovy 238 | 239 | 240 | Potentially confusing code constructsJavaScript 241 | 242 | 243 | Probable bugsCSS 244 | 245 | 246 | Probable bugsGroovy 247 | 248 | 249 | Probable bugsJava 250 | 251 | 252 | Probable bugsJavaScript 253 | 254 | 255 | Properties Files 256 | 257 | 258 | RELAX NG 259 | 260 | 261 | SQL 262 | 263 | 264 | Security issuesJava 265 | 266 | 267 | Serialization issuesJava 268 | 269 | 270 | Spelling 271 | 272 | 273 | Spring 274 | 275 | 276 | Spring AOPSpring 277 | 278 | 279 | Spring CoreSpring 280 | 281 | 282 | Spring OSGiSpring 283 | 284 | 285 | TestNGJava 286 | 287 | 288 | Threading issuesGroovy 289 | 290 | 291 | Threading issuesJava 292 | 293 | 294 | UI Form Problems 295 | 296 | 297 | Verbose or redundant code constructsJava 298 | 299 | 300 | Visibility issuesJava 301 | 302 | 303 | WSDL issues 304 | 305 | 306 | Web Services 307 | 308 | 309 | XML 310 | 311 | 312 | XMLSpring CoreSpring 313 | 314 | 315 | XPath 316 | 317 | 318 | XSLT 319 | 320 | 321 | 322 | 323 | Android 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 336 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/uiDesigner.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 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 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 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 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # my-rpc 2 | >了解RPC的一些原理后,尝试自己造个轮子,加深了解。 3 | 如果你对RPC的原理和运行机制还不够了解,我更希望你从最简单的版本开始了解。 4 | [https://github.com/yuyufeng1994/my-rpc/tree/v1](https://github.com/yuyufeng1994/my-rpc/tree/v1) 5 | 6 | 个人对rpc原理的见解 7 | --- 8 | >rpc是一种远程过程调用协议。rpc主要功能:异构分布式项目之间的通信,使消费者只需要知道接口,远程调用方法就像调用本地方法一样。 9 | 要使得消费层只通过接口调用远程实现方法,那么其之间的传输数据肯定是:类、方法、参数、返回值,以及一些其它传输的信息。 10 | 之间涉及到通信,肯定要发布服务供客户端请求。客户端要执行未知实现的方法,是通过动态代理实现的。 11 | 在了解动态代理的使用后,就会发现,在动态代理的方法执行过程中,可以不用去执行真实方法(invoke方法中),你可以获取到上面所需要的类、方法、参数、返回值等执行方法的参数。 12 | 那么把这些参数传输到远程去。在提供层接收到消费层方法的传参后,通过反射执行已经注册的类方法。(提供层要把暴露接口的实现类的方法注册到容器中,供查找) 13 | 自己编写rpc之前的所需的准备 14 | -- 15 | >了解了常用rpc框架dubbo的流程。复习了动态代理。复习了java io通信。 16 | 17 | 模块说明 18 | ------ 19 | #### rpc-core 20 | >这个模块是rpc的核心部分包括网络通信,客户端动态代理,通信数据结构,Spring结合模块 21 | #### rpc-service 22 | >这个模块rpc提供层暴露的接口 23 | #### rpc-provider 24 | >这个模块是rpc的提供层 25 | #### rpc-consumer 26 | >这个模块是rpc的消费层 27 | 28 | 依赖关系 29 | --- 30 | >rpc-consumer、rpc-provider为rpc使用方,所以他们两个都依赖 rpc-core 模块。 31 | 因为提供层要为消费层暴露接口,所以提取了公共接口,因此,它们两个都依赖rpc-service 32 | 33 | 34 | 启动调试 35 | -- 36 | * 使用HelloService接口进行调试。首先运行zookeeper服务,默认本地ip。 37 | * 启动提供层:在rpc-provider模块中运行top.yuyufeng.rpc.ServerApp.Main 38 | * 启动消费层:在rpc-consumer模块中运行top.yuyufeng.rpc.test.ClientApp.Main 39 | 40 | 启动调试(使用Spring) 41 | -- 42 | * 使用HelloService接口进行调试。首先运行zookeeper服务,默认本地ip。 43 | * 启动提供层:在rpc-provider模块中运行top.yuyufeng.rpc.ServerAppBySpring 44 | * 启动消费层:在rpc-consumer模块中运行top.yuyufeng.rpc.test.ClientAppSpring 45 | 46 | 缺陷 47 | -- 48 | * 消费降级等功能的有待实现 49 | >* ...(*细节有待实现*) 50 | 51 | 版本说明 52 | -- 53 | > 项目随着主干进行下去 54 | * [master](https://github.com/yuyufeng1994/my-rpc/) 55 | * [v4](https://github.com/yuyufeng1994/my-rpc/) 增加Cluster(负载)层,结合Spring启动 56 | * [v3](https://github.com/yuyufeng1994/my-rpc/tree/v3) 使用Netty4来操作NIO通信,不再是原来的多线程BIO。改变了通信方式,结构变化较大 57 | * [v2](https://github.com/yuyufeng1994/my-rpc/tree/v2) 在上个版本基础上,增加zookeeper注册发现,客户端服务端无需互相知道对方。增加Protostuff序列化(序列化效率高) 58 | * [v1](https://github.com/yuyufeng1994/my-rpc/tree/v1) 原始版本(bio多线程通信 客户端服务端直连) 59 | 60 | 61 | 更新日志 62 | ---- 63 | >* 2019年4月11日增加结合Spring启动,服务端服务实例单例化 64 | >* 2017年8月29日 增加Cluster(负载)层 65 | 之前初始版本已经建立分支[https://github.com/yuyufeng1994/my-rpc/tree/v3](https://github.com/yuyufeng1994/my-rpc/tree/v3) 66 | >* 2017年8月28日 将原来的BIO通信改成了NIO,加入*Netty4*进行通信 67 | 之前初始版本已经建立分支[https://github.com/yuyufeng1994/my-rpc/tree/v2](https://github.com/yuyufeng1994/my-rpc/tree/v2) 68 | >* 2017年8月24日 使用*zookeeper*来作协调服务注册与发现,使用*Protostuff*序列化(取代jdk序列化) 69 | 之前初始版本已经建立分支[https://github.com/yuyufeng1994/my-rpc/tree/v1](https://github.com/yuyufeng1994/my-rpc/tree/v1) 70 | -------------------------------------------------------------------------------- /my-rpc.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | top.yuyufeng 8 | my-rpc 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | 13 | 1.8 14 | 1.8 15 | 16 | 17 | 18 | 19 | rpc-consumer 20 | rpc-service 21 | rpc-provider 22 | rpc-core 23 | 24 | 25 | 26 | 27 | 28 | junit 29 | junit 30 | 4.12 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.apache.maven.plugins 39 | maven-surefire-plugin 40 | 2.19 41 | 42 | 43 | true 44 | -Dfile.encoding=UTF-8 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /rpc-consumer/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | my-rpc 7 | top.yuyufeng 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | rpc-consumer 13 | 14 | 15 | 16 | top.yuyufeng 17 | rpc-service 18 | 1.0-SNAPSHOT 19 | 20 | 21 | top.yuyufeng 22 | rpc-core 23 | 1.0-SNAPSHOT 24 | 25 | 26 | 27 | org.springframework 28 | spring-test 29 | 4.1.7.RELEASE 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /rpc-consumer/rpc-consumer.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /rpc-consumer/src/main/java/top/yuyufeng/rpc/test/ClientApp.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.test; 2 | 3 | import top.yuyufeng.rpc.client.proxy.RemoteServiceImpl; 4 | import top.yuyufeng.rpc.service.CalService; 5 | import top.yuyufeng.rpc.service.HelloService; 6 | import top.yuyufeng.rpc.service.top.yuyufeng.dto.MyResult; 7 | 8 | /** 9 | * 服务调用 (客户端) 10 | * @date 2017/8/19. 11 | * @author yuyufeng 12 | */ 13 | public class ClientApp { 14 | public static void main(String[] args) { 15 | //设置Zookeeper的地址 16 | RemoteServiceImpl.setZookeeperAddress("127.0.0.1:2181"); 17 | 18 | //获取动态代理的HelloService的“真实对象(其实内部不是真实的,被换成了调用远程方法)” 19 | HelloService helloService = RemoteServiceImpl.newRemoteProxyObject(HelloService.class); 20 | String result = helloService.sayHello("yyf"); 21 | System.out.println(result); 22 | 23 | CalService calService = RemoteServiceImpl.newRemoteProxyObject(CalService.class); 24 | MyResult myResult = calService.getResult(1, 2); 25 | System.out.println(myResult); 26 | 27 | myResult = calService.getResult(3, 2); 28 | System.out.println(myResult); 29 | 30 | /*//启动10个线程去请求 31 | for (int i = 0; i < 10; i++) { 32 | new Thread(){ 33 | @Override 34 | public void run() { 35 | for (int j = 0; j < 10; j++) { 36 | String result = helloService.sayHello("yyf"); 37 | System.out.println(result); 38 | MyResult myResult = calService.getResult(1,2); 39 | System.out.println(myResult); 40 | } 41 | } 42 | }.start(); 43 | }*/ 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /rpc-consumer/src/main/java/top/yuyufeng/rpc/test/ClientAppSpring.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.test; 2 | 3 | import org.springframework.context.support.ClassPathXmlApplicationContext; 4 | import top.yuyufeng.rpc.client.proxy.RemoteServiceImpl; 5 | import top.yuyufeng.rpc.service.CalService; 6 | import top.yuyufeng.rpc.service.HelloService; 7 | import top.yuyufeng.rpc.service.top.yuyufeng.dto.MyResult; 8 | 9 | /** 10 | * 服务调用 (客户端) 11 | * 12 | * @author yuyufeng 13 | * @date 2017/8/19. 14 | */ 15 | public class ClientAppSpring { 16 | public static void main(String[] args) { 17 | ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"my-rpc-consumer.xml"}); 18 | 19 | HelloService helloService = context.getBean(HelloService.class); 20 | String result = helloService.sayHello("yyf"); 21 | System.out.println(result); 22 | 23 | CalService calService = context.getBean(CalService.class); 24 | MyResult myResult = calService.getResult(1, 2); 25 | System.out.println(myResult); 26 | 27 | myResult = calService.getResult(3, 2); 28 | System.out.println(myResult); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rpc-consumer/src/main/resources/my-rpc-consumer.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /rpc-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | my-rpc 7 | top.yuyufeng 8 | 1.0-SNAPSHOT 9 | 10 | jar 11 | 4.0.0 12 | 13 | rpc-core 14 | 15 | 16 | 4.1.7.RELEASE 17 | 18 | 19 | 20 | 21 | org.apache.zookeeper 22 | zookeeper 23 | 3.4.6 24 | 25 | 26 | 27 | com.github.sgroschupf 28 | zkclient 29 | 0.1 30 | 31 | 32 | 33 | com.dyuproject.protostuff 34 | protostuff-api 35 | 1.0.10 36 | 37 | 38 | com.dyuproject.protostuff 39 | protostuff-core 40 | 1.0.10 41 | 42 | 43 | com.dyuproject.protostuff 44 | protostuff-runtime 45 | 1.0.10 46 | 47 | 48 | 49 | io.netty 50 | netty-all 51 | 4.1.14.Final 52 | 53 | 54 | 55 | 56 | org.springframework 57 | spring-core 58 | ${spring-version} 59 | 60 | 61 | 62 | org.springframework 63 | spring-beans 64 | ${spring-version} 65 | 66 | 67 | 68 | org.springframework 69 | spring-context 70 | ${spring-version} 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /rpc-core/rpc-core.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/MyDecoder.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.handler.codec.ByteToMessageDecoder; 6 | import top.yuyufeng.rpc.utils.ProtostuffUtil; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * Created by yuyufeng on 2017/8/28. 12 | */ 13 | public class MyDecoder extends ByteToMessageDecoder { 14 | private Class genericClass; 15 | 16 | public MyDecoder(Class genericClass) { 17 | this.genericClass = genericClass; 18 | } 19 | 20 | @Override 21 | public final void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { 22 | if (in.readableBytes() < 4) { 23 | return; 24 | } 25 | in.markReaderIndex(); 26 | int dataLength = in.readInt(); 27 | if (dataLength < 0) { 28 | ctx.close(); 29 | } 30 | if (in.readableBytes() < dataLength) { 31 | in.resetReaderIndex(); 32 | } 33 | byte[] data = new byte[dataLength]; 34 | in.readBytes(data); 35 | Object obj = ProtostuffUtil.deserializer(data, genericClass); 36 | out.add(obj); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/MyEncoder.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.handler.codec.MessageToByteEncoder; 6 | import top.yuyufeng.rpc.utils.ProtostuffUtil; 7 | 8 | /** 9 | * Created by yuyufeng on 2017/8/28. 10 | */ 11 | public class MyEncoder extends MessageToByteEncoder { 12 | private Class genericClass; 13 | 14 | public MyEncoder(Class genericClass) { 15 | this.genericClass = genericClass; 16 | } 17 | 18 | @Override 19 | public void encode(ChannelHandlerContext ctx, Object in, ByteBuf out) throws Exception { 20 | if (genericClass.isInstance(in)) { 21 | byte[] data = ProtostuffUtil.serializer(in); 22 | out.writeInt(data.length); 23 | out.writeBytes(data); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/RpcRequest.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc; 2 | 3 | import java.io.Serializable; 4 | import java.net.InetSocketAddress; 5 | import java.util.Arrays; 6 | 7 | /** 8 | * created by yuyufeng on 2017/8/19. 9 | */ 10 | public class RpcRequest{ 11 | private String serviceName; 12 | 13 | private String methodName; 14 | 15 | private Class[] parameterTypes; 16 | private Class returnType; 17 | 18 | private Object[] arguments; 19 | 20 | private String localAddress; 21 | 22 | private String remoteAddress; 23 | private long timeout = 10000; //超时 默认10秒 24 | 25 | public long getTimeout() { 26 | return timeout; 27 | } 28 | 29 | public void setTimeout(long timeout) { 30 | this.timeout = timeout; 31 | } 32 | 33 | public String getServiceName() { 34 | return serviceName; 35 | } 36 | 37 | public void setServiceName(String serviceName) { 38 | this.serviceName = serviceName; 39 | } 40 | 41 | public String getMethodName() { 42 | return methodName; 43 | } 44 | 45 | public void setMethodName(String methodName) { 46 | this.methodName = methodName; 47 | } 48 | 49 | public Class[] getParameterTypes() { 50 | return parameterTypes; 51 | } 52 | 53 | public void setParameterTypes(Class[] parameterTypes) { 54 | this.parameterTypes = parameterTypes; 55 | } 56 | 57 | public Object[] getArguments() { 58 | return arguments; 59 | } 60 | 61 | public void setArguments(Object[] arguments) { 62 | this.arguments = arguments; 63 | } 64 | 65 | public String getLocalAddress() { 66 | return localAddress; 67 | } 68 | 69 | public void setLocalAddress(String localAddress) { 70 | this.localAddress = localAddress; 71 | } 72 | 73 | public String getRemoteAddress() { 74 | return remoteAddress; 75 | } 76 | 77 | public void setRemoteAddress(String remoteAddress) { 78 | this.remoteAddress = remoteAddress; 79 | } 80 | 81 | public Class getReturnType() { 82 | return returnType; 83 | } 84 | 85 | public void setReturnType(Class returnType) { 86 | this.returnType = returnType; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/RpcResponse.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc; 2 | 3 | /** 4 | * Created by yuyufeng on 2017/8/28. 5 | */ 6 | public class RpcResponse { 7 | public RpcResponse() { 8 | } 9 | 10 | public RpcResponse(Object result) { 11 | this.result = result; 12 | } 13 | 14 | private Object result; 15 | 16 | public Object getResult() { 17 | return result; 18 | } 19 | 20 | public void setResult(Object result) { 21 | this.result = result; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/client/ClientCluster.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.client; 2 | 3 | import java.net.InetSocketAddress; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Random; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | 9 | /** 10 | * 负载,分配ip 11 | * 12 | * @author yuyufeng 13 | * @date 2018/1/9 14 | */ 15 | public class ClientCluster { 16 | 17 | 18 | /** 19 | * 当有多台服务器的时候,随机分配一台。规则可自定义 20 | * 21 | * @param serviceName 22 | * @return 23 | */ 24 | public static InetSocketAddress getServerIPByRandom(String serviceName) { 25 | List inetSocketAddressList = DiscoverService.discoverServices(serviceName); 26 | int length = inetSocketAddressList.size(); 27 | 28 | return inetSocketAddressList.get(new Random().nextInt(length)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/client/DiscoverService.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.client; 2 | 3 | import org.apache.zookeeper.KeeperException; 4 | import org.apache.zookeeper.ZooKeeper; 5 | 6 | import java.io.IOException; 7 | import java.net.InetSocketAddress; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.concurrent.ConcurrentHashMap; 12 | 13 | /** 14 | * @author yuyufeng 15 | * @date 2018/1/9 16 | */ 17 | public class DiscoverService { 18 | 19 | //zookeeper地址,默认本机2181接口 20 | private static String ZOOKEEPER_HOST = "localhost:2181"; 21 | private static Map> sevices = new ConcurrentHashMap<>(); 22 | private static final int TIME_OUT = 10000; 23 | 24 | public static List discoverServices(String serviceName) { 25 | List results = sevices.get(serviceName); 26 | if (results != null) { 27 | return results; 28 | } else { 29 | results = new ArrayList<>(); 30 | } 31 | 32 | ZooKeeper zookeeper = null; 33 | try { 34 | zookeeper = new ZooKeeper(ZOOKEEPER_HOST, TIME_OUT, null); 35 | } catch (IOException e) { 36 | e.printStackTrace(); 37 | } 38 | try { 39 | byte[] res = zookeeper.getData("/myrpc/" + serviceName, true, null); 40 | if (res == null) { 41 | System.err.println(serviceName + "服务没有发现..."); 42 | } 43 | String resIpStr = new String(res); 44 | String[] resIps = resIpStr.split(";"); 45 | System.out.println("发现服务: " + serviceName + " " + resIpStr); 46 | for (String resIp : resIps) { 47 | if (resIp == null || "".equals(resIp)) { 48 | continue; 49 | } 50 | try { 51 | InetSocketAddress result = new InetSocketAddress(resIp.split(":")[0], Integer.valueOf(resIp.split(":")[1])); 52 | results.add(result); 53 | } catch (Exception e) { 54 | } 55 | 56 | } 57 | sevices.put(serviceName, results); 58 | return results; 59 | } catch (KeeperException e) { 60 | System.err.println(serviceName + " 服务没有发现..."); 61 | } catch (InterruptedException e) { 62 | System.err.println(serviceName + " 服务没有发现..."); 63 | } finally { 64 | try { 65 | zookeeper.close(); 66 | } catch (InterruptedException e) { 67 | e.printStackTrace(); 68 | } 69 | } 70 | return null; 71 | } 72 | 73 | 74 | public static void setZookeeperHost(String zookeeperHost) { 75 | ZOOKEEPER_HOST = zookeeperHost; 76 | } 77 | 78 | 79 | /** 80 | * 优化 81 | * 这里可以增加一个定时器,其扫描服务端的服务是否可用,如果不可用,剔除 sevices 82 | */ 83 | 84 | 85 | } 86 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/client/MyClientHandler.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.client; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.channel.ChannelInboundHandlerAdapter; 5 | 6 | /** 7 | * Netty适配器 8 | * @author yuyufeng 9 | * @date 2017/8/28 10 | */ 11 | public class MyClientHandler extends ChannelInboundHandlerAdapter { 12 | 13 | private Object result; 14 | 15 | 16 | 17 | public Object getResult() { 18 | return result; 19 | } 20 | public void setResult(Object result) { 21 | this.result = result; 22 | } 23 | 24 | @Override 25 | public void channelActive(ChannelHandlerContext ctx) { 26 | // System.out.println("MyClientHandler.channelActive"); 27 | } 28 | 29 | @Override 30 | public void channelRead(ChannelHandlerContext ctx, Object msg) { 31 | // System.out.println("read Message:"+msg); 32 | result = msg; 33 | } 34 | 35 | @Override 36 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 37 | cause.printStackTrace(); 38 | ctx.close(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/client/MyNettyClient.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.client; 2 | 3 | import io.netty.bootstrap.Bootstrap; 4 | import io.netty.channel.*; 5 | import io.netty.channel.nio.NioEventLoopGroup; 6 | import io.netty.channel.socket.SocketChannel; 7 | import io.netty.channel.socket.nio.NioSocketChannel; 8 | import top.yuyufeng.rpc.MyDecoder; 9 | import top.yuyufeng.rpc.MyEncoder; 10 | import top.yuyufeng.rpc.RpcRequest; 11 | import top.yuyufeng.rpc.RpcResponse; 12 | 13 | import java.net.InetSocketAddress; 14 | 15 | 16 | /** 17 | * 客户端Netty实现 18 | * 19 | * @author yuyufeng 20 | * @date 2017/8/28 21 | */ 22 | public class MyNettyClient { 23 | private static Integer TIMEOUT = 1000; 24 | 25 | public static Object send(RpcRequest rpcRequest, InetSocketAddress inetSocketAddress) { 26 | MyClientHandler myClientHandler = new MyClientHandler(); 27 | // Configure the client. 28 | EventLoopGroup group = new NioEventLoopGroup(); 29 | try { 30 | Bootstrap b = new Bootstrap(); 31 | b.group(group) 32 | .channel(NioSocketChannel.class) 33 | .option(ChannelOption.TCP_NODELAY, true) 34 | .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, TIMEOUT) 35 | .handler(new ChannelInitializer() { 36 | @Override 37 | public void initChannel(SocketChannel ch) throws Exception { 38 | ChannelPipeline p = ch.pipeline(); 39 | ch.pipeline().addLast(new MyEncoder(RpcRequest.class)); 40 | ch.pipeline().addLast(new MyDecoder(RpcResponse.class)); 41 | ch.pipeline().addLast(myClientHandler); 42 | } 43 | }); 44 | 45 | ChannelFuture future = b.connect(inetSocketAddress.getAddress(), inetSocketAddress.getPort()).sync(); 46 | future.channel().writeAndFlush(rpcRequest); 47 | 48 | future.channel().closeFuture().sync(); 49 | } catch (InterruptedException e) { 50 | e.printStackTrace(); 51 | } finally { 52 | group.shutdownGracefully(); 53 | } 54 | return myClientHandler.getResult(); 55 | } 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/client/proxy/ProxyHandler.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.client.proxy; 2 | 3 | 4 | import org.apache.zookeeper.KeeperException; 5 | import org.apache.zookeeper.ZooKeeper; 6 | import top.yuyufeng.rpc.RpcRequest; 7 | import top.yuyufeng.rpc.RpcResponse; 8 | import top.yuyufeng.rpc.client.ClientCluster; 9 | import top.yuyufeng.rpc.client.DiscoverService; 10 | import top.yuyufeng.rpc.client.MyNettyClient; 11 | import top.yuyufeng.rpc.utils.ProtostuffUtil; 12 | 13 | import java.io.*; 14 | import java.lang.reflect.InvocationHandler; 15 | import java.lang.reflect.Method; 16 | import java.net.InetSocketAddress; 17 | import java.net.Socket; 18 | import java.net.UnknownHostException; 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | import java.util.concurrent.*; 22 | 23 | /** 24 | * 动态代理处理程序 25 | * @date 2017/8/18. 26 | * @author yuyufeng 27 | */ 28 | public class ProxyHandler implements InvocationHandler { 29 | private Class service; 30 | //远程调用地址 31 | private InetSocketAddress remoteAddress; 32 | 33 | 34 | public ProxyHandler(Class service) { 35 | this.service = service; 36 | } 37 | 38 | @Override 39 | public Object invoke(Object object, Method method, Object[] args) throws Throwable { 40 | //准备传输的对象 41 | RpcRequest rpcRequest = new RpcRequest(); 42 | rpcRequest.setServiceName(service.getName()); 43 | rpcRequest.setMethodName(method.getName()); 44 | rpcRequest.setArguments(args); 45 | rpcRequest.setParameterTypes(method.getParameterTypes()); 46 | rpcRequest.setReturnType(method.getReturnType()); 47 | return this.request(rpcRequest); 48 | } 49 | 50 | private Object request(RpcRequest rpcRequest) throws ClassNotFoundException { 51 | //获取需要请求的地址 52 | remoteAddress = ClientCluster.getServerIPByRandom(rpcRequest.getServiceName()); 53 | if (remoteAddress == null) { 54 | return null; 55 | } 56 | Object result; 57 | RpcResponse rpcResponse = (RpcResponse) MyNettyClient.send(rpcRequest,remoteAddress); 58 | result = rpcResponse.getResult(); 59 | return result; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/client/proxy/RemoteServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.client.proxy; 2 | 3 | import top.yuyufeng.rpc.client.DiscoverService; 4 | 5 | import java.lang.reflect.Proxy; 6 | import java.util.concurrent.ExecutorService; 7 | import java.util.concurrent.Executors; 8 | 9 | /** 10 | * @author yuyufeng 11 | * @date 2017/8/19. 12 | */ 13 | public class RemoteServiceImpl { 14 | /** 15 | * 动态代理的真实对象的实现 16 | * 17 | * @param service 18 | * @param 19 | * @return 20 | */ 21 | public static T newRemoteProxyObject(final Class service) { 22 | return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service}, new ProxyHandler(service)); 23 | } 24 | 25 | 26 | /** 27 | * 设置Zookeeper的地址,默认为本机2181接口 28 | * @param address 29 | */ 30 | public static void setZookeeperAddress(String address) { 31 | DiscoverService.setZookeeperHost(address); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/client/spring/MyRpcReference.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.client.spring; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.beans.factory.DisposableBean; 5 | import org.springframework.beans.factory.InitializingBean; 6 | import org.springframework.beans.factory.support.DefaultListableBeanFactory; 7 | import org.springframework.context.ApplicationContext; 8 | import org.springframework.context.ApplicationContextAware; 9 | import top.yuyufeng.rpc.client.proxy.RemoteServiceImpl; 10 | 11 | import java.util.Map; 12 | 13 | /** 14 | * @author yuyufeng 15 | * @date 2019/4/10. 16 | */ 17 | public class MyRpcReference implements ApplicationContextAware, InitializingBean, DisposableBean { 18 | 19 | private DefaultListableBeanFactory beanFactory; 20 | /** 21 | * 远程接口 22 | */ 23 | private Map references; 24 | 25 | public void setReferences(Map references) { 26 | this.references = references; 27 | } 28 | 29 | @Override 30 | public void destroy() throws Exception { 31 | 32 | } 33 | 34 | @Override 35 | public void afterPropertiesSet() throws Exception { 36 | for (String key : references.keySet()) { 37 | Class clazz = references.get(key); 38 | Object object = RemoteServiceImpl.newRemoteProxyObject(clazz); 39 | //注入Spring容器 40 | beanFactory.registerSingleton(key, object); 41 | } 42 | } 43 | 44 | @Override 45 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 46 | beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/exception/RpcException.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.exception; 2 | 3 | /** 4 | * 异常处理类 5 | * @date 2017/8/19. 6 | * @author yuyufeng 7 | */ 8 | public class RpcException extends Exception { 9 | public RpcException() { 10 | super(); 11 | } 12 | 13 | public RpcException(String message) { 14 | super(message); 15 | } 16 | 17 | public RpcException(String message, Throwable cause) { 18 | super(message, cause); 19 | } 20 | 21 | public RpcException(Throwable cause) { 22 | super(cause); 23 | } 24 | 25 | protected RpcException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 26 | super(message, cause, enableSuppression, writableStackTrace); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/server/MyServer.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.server; 2 | 3 | import io.netty.bootstrap.ServerBootstrap; 4 | import io.netty.channel.ChannelFuture; 5 | import io.netty.channel.ChannelInitializer; 6 | import io.netty.channel.ChannelOption; 7 | import io.netty.channel.EventLoopGroup; 8 | import io.netty.channel.nio.NioEventLoopGroup; 9 | import io.netty.channel.socket.SocketChannel; 10 | import io.netty.channel.socket.nio.NioServerSocketChannel; 11 | import top.yuyufeng.rpc.MyDecoder; 12 | import top.yuyufeng.rpc.MyEncoder; 13 | import top.yuyufeng.rpc.RpcRequest; 14 | import top.yuyufeng.rpc.RpcResponse; 15 | 16 | import java.net.InetSocketAddress; 17 | 18 | /** 19 | * 服务 20 | * @author yuyufeng 21 | * @date 2017/8/28 22 | */ 23 | public class MyServer { 24 | private int port; 25 | private int threadSize = 5; 26 | private EventLoopGroup bossGroup; 27 | private EventLoopGroup workerGroup; 28 | 29 | public MyServer(int port,int threadSize) { 30 | this.port = port; 31 | this.threadSize = threadSize; 32 | } 33 | 34 | public void start() { 35 | bossGroup = new NioEventLoopGroup(threadSize); 36 | workerGroup = new NioEventLoopGroup(); 37 | try { 38 | ServerBootstrap sbs = new ServerBootstrap().group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).localAddress(new InetSocketAddress(port)) 39 | .childHandler(new ChannelInitializer() { 40 | 41 | protected void initChannel(SocketChannel ch) throws Exception { 42 | // ch.pipeline().addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); 43 | ch.pipeline().addLast(new MyDecoder(RpcRequest.class)); 44 | ch.pipeline().addLast(new MyEncoder(RpcResponse.class)); 45 | ch.pipeline().addLast(new MyServerHandler()); 46 | } 47 | 48 | ; 49 | 50 | }).option(ChannelOption.SO_BACKLOG, 128) 51 | .childOption(ChannelOption.SO_KEEPALIVE, true); 52 | // 绑定端口,开始接收进来的连接 53 | ChannelFuture future = sbs.bind(port).sync(); 54 | System.out.println("Rpc服务启动成功 " + port); 55 | future.channel().closeFuture().sync(); 56 | } catch (Exception e) { 57 | bossGroup.shutdownGracefully(); 58 | workerGroup.shutdownGracefully(); 59 | } 60 | } 61 | 62 | public void shutdown(){ 63 | bossGroup.shutdownGracefully(); 64 | workerGroup.shutdownGracefully(); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/server/MyServerHandler.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.server; 2 | 3 | import io.netty.channel.ChannelFutureListener; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.channel.ChannelInboundHandlerAdapter; 6 | import top.yuyufeng.rpc.RpcRequest; 7 | import top.yuyufeng.rpc.RpcResponse; 8 | import top.yuyufeng.rpc.exception.RpcException; 9 | import top.yuyufeng.rpc.utils.ProtostuffUtil; 10 | 11 | import java.lang.reflect.Method; 12 | import java.util.Date; 13 | import java.util.Map; 14 | import java.util.concurrent.ConcurrentHashMap; 15 | 16 | /** 17 | * @author yuyufeng 18 | * @date 2017/8/28 19 | */ 20 | public class MyServerHandler extends ChannelInboundHandlerAdapter { 21 | /** 22 | * 单利存放实例化之后的服务 23 | */ 24 | private static Map serviceObjects = new ConcurrentHashMap<>(); 25 | 26 | @Override 27 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 28 | RpcRequest rpcRequest = (RpcRequest) msg; 29 | Class clazz = RegisterServicesCenter.getService(rpcRequest.getServiceName()); 30 | if (clazz == null) { 31 | throw new RpcException("没有找到类 " + rpcRequest.getServiceName()); 32 | } 33 | Method method = clazz.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes()); 34 | if (method == null) { 35 | throw new RpcException("没有找到相应方法 " + rpcRequest.getMethodName()); 36 | } 37 | //执行真正要调用的方法。 38 | Object object = serviceObjects.get(clazz.getName()); 39 | if (object == null) { 40 | object = clazz.newInstance(); 41 | serviceObjects.put(clazz.getName(), object); 42 | } 43 | Object result = method.invoke(clazz.newInstance(), rpcRequest.getArguments()); 44 | //返回执行结果给客户端 45 | RpcResponse rpcResponse = new RpcResponse(result); 46 | ctx.writeAndFlush(rpcResponse).addListener(ChannelFutureListener.CLOSE); 47 | } 48 | 49 | @Override 50 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 51 | cause.printStackTrace(); 52 | ctx.close(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/server/RegisterServicesCenter.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.server; 2 | 3 | import org.apache.zookeeper.CreateMode; 4 | import org.apache.zookeeper.KeeperException; 5 | import org.apache.zookeeper.ZooDefs; 6 | import org.apache.zookeeper.ZooKeeper; 7 | 8 | import java.io.IOException; 9 | import java.net.InetAddress; 10 | import java.util.concurrent.ConcurrentHashMap; 11 | 12 | 13 | /** 14 | * 服务注册中心 15 | * 16 | * @author yuyufeng 17 | */ 18 | public class RegisterServicesCenter { 19 | private static String zookeeperAddress; 20 | private static ZooKeeper zookeeper; 21 | private static int TIME_OUT = 10000; 22 | private static String localIp; 23 | 24 | public static void init(String zookeeperAddress, int localPort) { 25 | RegisterServicesCenter.zookeeperAddress = zookeeperAddress; 26 | try { 27 | zookeeper = new ZooKeeper(zookeeperAddress, TIME_OUT, null); 28 | //提供层的ip,这里存放本机的ip 29 | localIp = InetAddress.getLocalHost().getHostAddress() + ":" + localPort; 30 | } catch (IOException e) { 31 | e.printStackTrace(); 32 | } 33 | } 34 | 35 | /** 36 | * 暴露接口的实现类存放容器 37 | */ 38 | private static ConcurrentHashMap registerServices = new ConcurrentHashMap<>(); 39 | 40 | /** 41 | * 增加服务 42 | * 43 | * @param className 44 | * @param clazz 45 | * @throws InterruptedException 46 | */ 47 | public static void addServices(String className, Class clazz) throws InterruptedException { 48 | registerServices.put(className, clazz); 49 | //存入zookeeper节点 50 | //后期优化增强:一个服务可配置多个ip,这样就可以有多个提供层提供服务,在客户端使用负载均衡策略即可 51 | try { 52 | 53 | if (zookeeper.exists("/myrpc", false) == null) { 54 | zookeeper.create("/myrpc", "true".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); 55 | } 56 | 57 | 58 | if (zookeeper.exists("/myrpc/" + className, false) == null) { 59 | zookeeper.create("/myrpc/" + className, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); 60 | } 61 | 62 | 63 | /* if (zookeeper.exists("/myrpc/" + className, false) != null) { 64 | zookeeper.delete("/myrpc/" + className, -1); 65 | }*/ 66 | 67 | byte[] ipsBytes = zookeeper.getData("/myrpc/" + className, false, null); 68 | 69 | String ips = new String(ipsBytes); 70 | ips += ";" + localIp; 71 | 72 | //把当前服务的ip地址存如zookeeper中,供消费者-发现 73 | zookeeper.setData("/myrpc/" + className, ips.getBytes(), -1); 74 | ipsBytes = zookeeper.getData("/myrpc/" + className, false, null); 75 | System.out.println("服务:" + className + " " + new String(ipsBytes) + " 注册完成"); 76 | 77 | } catch (KeeperException e) { 78 | e.printStackTrace(); 79 | } finally { 80 | // zookeeper.close(); 81 | } 82 | } 83 | 84 | /** 85 | * 根据类名获取服务 86 | * 87 | * @param className 88 | * @return 89 | */ 90 | public static Class getService(String className) { 91 | return registerServices.get(className); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/server/RpcServer.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.server; 2 | 3 | /** 4 | * RPC服务 5 | * @date 2017/8/19. 6 | * @author yuyufeng 7 | */ 8 | public interface RpcServer { 9 | /** 10 | * 启动rpc服务 11 | */ 12 | void start(); 13 | 14 | /** 15 | * 停止rpc服务 16 | */ 17 | void stop(); 18 | 19 | /** 20 | * 把服务注册进rpc 21 | */ 22 | void register(String className, Class clazz) throws Exception; 23 | 24 | /** 25 | * rpc 服务是否存活 26 | * @return 27 | */ 28 | boolean isAlive(); 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/server/RpcServerImpl.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.server; 2 | 3 | import top.yuyufeng.rpc.exception.RpcException; 4 | 5 | import java.io.IOException; 6 | import java.net.ServerSocket; 7 | import java.util.Date; 8 | import java.util.concurrent.ExecutorService; 9 | import java.util.concurrent.Executors; 10 | 11 | /** 12 | * created by yuyufeng on 2017/8/19. 13 | */ 14 | public class RpcServerImpl implements RpcServer { 15 | private int nThreads = 10; 16 | private boolean isAlive = false; 17 | private int port = 8989; 18 | private MyServer myServer; 19 | private final static ExecutorService executor = Executors.newSingleThreadExecutor(); 20 | 21 | public RpcServerImpl() { 22 | init(); 23 | } 24 | 25 | 26 | public RpcServerImpl(int port, int nThreads, String zookeeperHost, Boolean isStart) { 27 | this.port = port; 28 | this.nThreads = nThreads; 29 | RegisterServicesCenter.init(zookeeperHost, port); 30 | init(); 31 | if (isStart.equals(Boolean.TRUE)) { 32 | start(); 33 | } 34 | } 35 | 36 | public void init() { 37 | 38 | } 39 | 40 | @Override 41 | public void start() { 42 | synchronized (this){ 43 | if(isAlive){ 44 | return; 45 | } 46 | } 47 | System.out.println("开始启动Rpc服务 线程数:" + nThreads); 48 | isAlive = true; 49 | executor.execute(new Runnable() { 50 | @Override 51 | public void run() { 52 | myServer = new MyServer(port, nThreads); 53 | myServer.start(); 54 | } 55 | }); 56 | } 57 | 58 | @Override 59 | public void stop() { 60 | isAlive = false; 61 | myServer.shutdown(); 62 | } 63 | 64 | @Override 65 | public void register(String className, Class clazz) throws Exception { 66 | RegisterServicesCenter.addServices(className, clazz); 67 | } 68 | 69 | @Override 70 | public boolean isAlive() { 71 | String status = (this.isAlive == true) ? "RPC服务已经启动" : "RPC服务已经关闭"; 72 | System.out.println(status); 73 | return this.isAlive; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/server/spring/MyRpcConfig.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.server.spring; 2 | 3 | /** 4 | * @author yuyufeng 5 | * @date 2019/4/10. 6 | */ 7 | public class MyRpcConfig { 8 | private Integer port; 9 | private Integer nThreads; 10 | private String zookeeperAddress; 11 | 12 | public MyRpcConfig() { 13 | 14 | } 15 | 16 | 17 | public Integer getPort() { 18 | return port; 19 | } 20 | 21 | public void setPort(Integer port) { 22 | this.port = port; 23 | } 24 | 25 | public Integer getnThreads() { 26 | return nThreads; 27 | } 28 | 29 | public void setnThreads(Integer nThreads) { 30 | this.nThreads = nThreads; 31 | } 32 | 33 | public String getZookeeperAddress() { 34 | return zookeeperAddress; 35 | } 36 | 37 | public void setZookeeperAddress(String zookeeperAddress) { 38 | this.zookeeperAddress = zookeeperAddress; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/server/spring/RpcServerFactory.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.server.spring; 2 | 3 | import org.springframework.beans.factory.DisposableBean; 4 | import org.springframework.beans.factory.InitializingBean; 5 | import top.yuyufeng.rpc.server.RpcServer; 6 | import top.yuyufeng.rpc.server.RpcServerImpl; 7 | 8 | import java.util.Map; 9 | 10 | /** 11 | * 用户读取xml中的接口 12 | * 13 | * @author yuyufeng 14 | * @date 2019/4/10. 15 | */ 16 | 17 | public class RpcServerFactory implements InitializingBean, DisposableBean { 18 | 19 | private MyRpcConfig myRpcConfig; 20 | private RpcServer rpcServer; 21 | private Map services; 22 | 23 | public RpcServerFactory() { 24 | } 25 | 26 | public void setMyRpcConfig(MyRpcConfig myRpcConfig) { 27 | this.myRpcConfig = myRpcConfig; 28 | } 29 | 30 | 31 | public void setServices(Map services) { 32 | this.services = services; 33 | } 34 | 35 | @Override 36 | public void afterPropertiesSet() throws Exception { 37 | this.build(myRpcConfig); 38 | } 39 | 40 | public void build(MyRpcConfig config) { 41 | this.rpcServer = new RpcServerImpl(config.getPort(), config.getnThreads(), config.getZookeeperAddress(), false); 42 | for (String key : services.keySet()) { 43 | try { 44 | rpcServer.register(key,services.get(key)); 45 | } catch (Exception e) { 46 | e.printStackTrace(); 47 | } 48 | } 49 | //启动rpc服务 50 | rpcServer.start(); 51 | } 52 | 53 | @Override 54 | public void destroy() throws Exception { 55 | this.rpcServer.stop(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /rpc-core/src/main/java/top/yuyufeng/rpc/utils/ProtostuffUtil.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.utils; 2 | 3 | import com.dyuproject.protostuff.LinkedBuffer; 4 | import com.dyuproject.protostuff.ProtostuffIOUtil; 5 | import com.dyuproject.protostuff.Schema; 6 | import com.dyuproject.protostuff.runtime.RuntimeSchema; 7 | 8 | import java.util.Map; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | /** 12 | * 序列化工具 13 | * @author yuyufeng 14 | */ 15 | public class ProtostuffUtil { 16 | 17 | private static Map, Schema> cachedSchema = new ConcurrentHashMap, Schema>(); 18 | 19 | private static Schema getSchema(Class clazz) { 20 | @SuppressWarnings("unchecked") 21 | Schema schema = (Schema) cachedSchema.get(clazz); 22 | if (schema == null) { 23 | schema = RuntimeSchema.getSchema(clazz); 24 | if (schema != null) { 25 | cachedSchema.put(clazz, schema); 26 | } 27 | } 28 | return schema; 29 | } 30 | 31 | /** 32 | * 序列化 33 | * 34 | * @param obj 35 | * @return 36 | */ 37 | public static byte[] serializer(T obj) { 38 | @SuppressWarnings("unchecked") 39 | Class clazz = (Class) obj.getClass(); 40 | LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); 41 | try { 42 | Schema schema = getSchema(clazz); 43 | return ProtostuffIOUtil.toByteArray(obj, schema, buffer); 44 | } catch (Exception e) { 45 | throw new IllegalStateException(e.getMessage(), e); 46 | } finally { 47 | buffer.clear(); 48 | } 49 | } 50 | 51 | /** 52 | * 反序列化 53 | * 54 | * @param data 55 | * @param clazz 56 | * @return 57 | */ 58 | public static T deserializer(byte[] data, Class clazz) { 59 | try { 60 | T obj = clazz.newInstance(); 61 | Schema schema = getSchema(clazz); 62 | ProtostuffIOUtil.mergeFrom(data, obj, schema); 63 | return obj; 64 | } catch (Exception e) { 65 | throw new IllegalStateException(e.getMessage(), e); 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /rpc-provider/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | my-rpc 7 | top.yuyufeng 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | rpc-provider 13 | 14 | 15 | top.yuyufeng 16 | rpc-service 17 | 1.0-SNAPSHOT 18 | 19 | 20 | top.yuyufeng 21 | rpc-core 22 | 1.0-SNAPSHOT 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /rpc-provider/rpc-provider.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /rpc-provider/src/main/java/top/yuyufeng/rpc/ServerApp.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc; 2 | 3 | 4 | import top.yuyufeng.rpc.server.RpcServer; 5 | import top.yuyufeng.rpc.server.RpcServerImpl; 6 | import top.yuyufeng.rpc.service.CalService; 7 | import top.yuyufeng.rpc.service.HelloService; 8 | import top.yuyufeng.rpc.service.impl.CalServiceImpl; 9 | import top.yuyufeng.rpc.service.impl.HelloServiceImpl; 10 | 11 | /** 12 | * 服务启动 13 | * @date 2017/8/19. 14 | * @author yuyufeng 15 | */ 16 | public class ServerApp { 17 | public static void main(String[] args) throws Exception { 18 | RpcServer rpcServer = new RpcServerImpl(7878,5,"127.0.0.1:2181",true); 19 | //暴露HelloService接口,具体实现为HelloServiceImpl 20 | rpcServer.register(HelloService.class.getName(),HelloServiceImpl.class); 21 | rpcServer.register(CalService.class.getName(),CalServiceImpl.class); 22 | //启动rpc服务 23 | rpcServer.start(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /rpc-provider/src/main/java/top/yuyufeng/rpc/ServerAppBySpring.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc; 2 | 3 | import org.springframework.context.support.ClassPathXmlApplicationContext; 4 | 5 | import java.io.IOException; 6 | 7 | /** 8 | * 通过Spring方式启动 9 | * @author yuyufeng 10 | */ 11 | public class ServerAppBySpring { 12 | public static void main(String[] args) throws IOException { 13 | ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"my-rpc-provider.xml"}); 14 | context.start(); 15 | System.in.read(); // 按任意键退出 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /rpc-provider/src/main/java/top/yuyufeng/rpc/service/impl/CalServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.service.impl; 2 | 3 | import top.yuyufeng.rpc.service.CalService; 4 | import top.yuyufeng.rpc.service.top.yuyufeng.dto.MyResult; 5 | 6 | 7 | /** 8 | * 测试Service CalServiceImpl 9 | * @author yuyufeng 10 | */ 11 | public class CalServiceImpl implements CalService { 12 | private String name = "yyf"; 13 | 14 | @Override 15 | public MyResult getResult(int a, int b) { 16 | MyResult myResult = new MyResult(); 17 | myResult.setId(2017L); 18 | myResult.setName(name); 19 | myResult.setResult(a + b); 20 | return myResult; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /rpc-provider/src/main/java/top/yuyufeng/rpc/service/impl/HelloServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.service.impl; 2 | 3 | import top.yuyufeng.rpc.service.HelloService; 4 | 5 | /** 6 | * 测试Service HelloServiceImpl 7 | * @author yuyufeng 8 | */ 9 | public class HelloServiceImpl implements HelloService { 10 | @Override 11 | public String sayHello(String words) { 12 | System.out.println("hello:" + words); 13 | /* try { 14 | Thread.sleep(3000); 15 | } catch (InterruptedException e) { 16 | e.printStackTrace(); 17 | }*/ 18 | return "hello:" + words; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /rpc-provider/src/main/resources/my-rpc-provider.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /rpc-service/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | my-rpc 7 | top.yuyufeng 8 | 1.0-SNAPSHOT 9 | 10 | jar 11 | 4.0.0 12 | 13 | rpc-service 14 | 15 | 16 | -------------------------------------------------------------------------------- /rpc-service/rpc-service.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /rpc-service/src/main/java/top/yuyufeng/rpc/service/CalService.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.service; 2 | 3 | import top.yuyufeng.rpc.service.top.yuyufeng.dto.MyResult; 4 | 5 | /** 6 | * Created by yuyufeng on 2017/8/24. 7 | */ 8 | public interface CalService { 9 | MyResult getResult(int a, int b) ; 10 | } 11 | -------------------------------------------------------------------------------- /rpc-service/src/main/java/top/yuyufeng/rpc/service/HelloService.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.service; 2 | 3 | /** 4 | * created by yuyufeng on 2017/8/18. 5 | */ 6 | public interface HelloService { 7 | String sayHello(String words); 8 | } 9 | -------------------------------------------------------------------------------- /rpc-service/src/main/java/top/yuyufeng/rpc/service/top/yuyufeng/dto/MyResult.java: -------------------------------------------------------------------------------- 1 | package top.yuyufeng.rpc.service.top.yuyufeng.dto; 2 | 3 | /** 4 | * 测试实体类 5 | * @author yuyufeng 6 | * @date 2017/8/24 7 | */ 8 | public class MyResult{ 9 | private Long id; 10 | private String name; 11 | private Integer result; 12 | 13 | public Integer getResult() { 14 | return result; 15 | } 16 | 17 | public void setResult(Integer result) { 18 | this.result = result; 19 | } 20 | 21 | public Long getId() { 22 | return id; 23 | } 24 | 25 | public void setId(Long id) { 26 | this.id = id; 27 | } 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "MyResult{" + 40 | "id=" + id + 41 | ", name='" + name + '\'' + 42 | ", result=" + result + 43 | '}'; 44 | } 45 | } 46 | --------------------------------------------------------------------------------