├── laopopo-console └── src │ └── main │ ├── resources │ ├── rpc.properties │ ├── logback.xml │ ├── spring-rpc.xml │ └── spring-servlet.xml │ ├── webapp │ ├── resources │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ ├── css │ │ │ └── starter-template.css │ │ └── js │ │ │ └── locale │ │ │ └── bootstrap-table-zh-CN.min.js │ ├── model.html │ ├── WEB-INF │ │ └── web.xml │ └── index.html │ └── java │ └── org │ └── laopopo │ └── console │ ├── info │ └── kaleidoscope │ │ └── package-info.java │ ├── model │ └── ManagerRPC.java │ └── web │ └── controller │ └── MonitorCoreController.java ├── laopopo-common ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── services │ │ │ └── org.laopopo.common.serialization.Serializer │ │ └── java │ │ └── org │ │ └── laopopo │ │ └── common │ │ ├── rpc │ │ ├── package-info.java │ │ ├── ServiceReviewState.java │ │ ├── ManagerServiceRequestType.java │ │ └── MetricsReporter.java │ │ ├── loadbalance │ │ ├── package-info.java │ │ └── LoadBalanceStrategy.java │ │ ├── exception │ │ ├── package-info.java │ │ ├── rpc │ │ │ ├── package-info.java │ │ │ ├── NoServiceException.java │ │ │ ├── ProviderHandlerException.java │ │ │ ├── RpcWrapperException.java │ │ │ └── RemoteException.java │ │ └── remoting │ │ │ ├── RemotingException.java │ │ │ ├── RemotingNoSighException.java │ │ │ ├── RemotingContextException.java │ │ │ ├── RemotingCommmonCustomException.java │ │ │ ├── RemotingSendRequestException.java │ │ │ └── RemotingTimeoutException.java │ │ ├── spi │ │ └── BaseServiceLoader.java │ │ ├── transport │ │ └── body │ │ │ ├── CommonCustomBody.java │ │ │ ├── SubscribeRequestCustomBody.java │ │ │ ├── MetricsCustomBody.java │ │ │ ├── OfflineNoticeCustomBody.java │ │ │ ├── ProviderMetricsCustomBody.java │ │ │ ├── AckCustomBody.java │ │ │ ├── SubcribeResultCustomBody.java │ │ │ ├── RequestCustomBody.java │ │ │ ├── ResponseCustomBody.java │ │ │ ├── RequestReviewCustomBody.java │ │ │ └── ManagerServiceCustomBody.java │ │ ├── serialization │ │ ├── SerializerHolder.java │ │ ├── Serializer.java │ │ ├── fastjson │ │ │ └── FastjsonSerializer.java │ │ ├── kryo │ │ │ └── KryoSerializer.java │ │ └── proto │ │ │ └── ProtoStuffSerializer.java │ │ ├── utils │ │ ├── NativeSupport.java │ │ ├── Constants.java │ │ ├── Pair.java │ │ ├── ChannelGroup.java │ │ ├── UnresolvedAddress.java │ │ ├── Status.java │ │ ├── NamedThreadFactory.java │ │ ├── SystemClock.java │ │ ├── PersistUtils.java │ │ └── NettyChannelGroup.java │ │ └── protocal │ │ └── LaopopoProtocol.java └── pom.xml ├── laopopo-example ├── src │ └── main │ │ ├── java │ │ └── org │ │ │ └── laopopo │ │ │ └── example │ │ │ ├── demo │ │ │ └── service │ │ │ │ ├── ByeService.java │ │ │ │ ├── HelloSerivce.java │ │ │ │ ├── HelloServiceMock.java │ │ │ │ ├── ByeServiceImpl.java │ │ │ │ ├── HelloService_1.java │ │ │ │ ├── HelloService_2.java │ │ │ │ ├── HelloService_3.java │ │ │ │ ├── HelloServiceBenchmark.java │ │ │ │ └── HelloSerivceImpl.java │ │ │ ├── benchmark │ │ │ ├── package-info.java │ │ │ ├── big_request │ │ │ │ └── package-info.java │ │ │ ├── big_request_compress │ │ │ │ └── package-info.java │ │ │ ├── BenchmarkRegistryTest.java │ │ │ └── BenchmarkProviderTest.java │ │ │ ├── compress │ │ │ └── package-info.java │ │ │ ├── netty │ │ │ ├── package-info.java │ │ │ ├── example_1 │ │ │ │ ├── package-info.java │ │ │ │ └── NettyTransporterTest1.java │ │ │ ├── NettyClientTest.java │ │ │ ├── NettyServerTest.java │ │ │ └── TestCommonCustomBody.java │ │ │ ├── spring │ │ │ ├── package-info.java │ │ │ ├── HelloService.java │ │ │ ├── SpringProviderTest.java │ │ │ └── SpringConsumerTest.java │ │ │ ├── other │ │ │ ├── package-info.java │ │ │ └── StackCopyTest.java │ │ │ ├── persist │ │ │ ├── package-info.java │ │ │ ├── Teacher.java │ │ │ ├── Student.java │ │ │ ├── FastjsonTest.java │ │ │ └── FileToJsonTest.java │ │ │ ├── serializer │ │ │ ├── package-info.java │ │ │ └── SerializerTest.java │ │ │ ├── flow │ │ │ └── controller │ │ │ │ └── package-info.java │ │ │ └── generic │ │ │ ├── test_7 │ │ │ ├── package-info.java │ │ │ ├── HelloService.java │ │ │ ├── ProviderTest_3.java │ │ │ ├── ProviderTest_1.java │ │ │ ├── ProviderTest_2.java │ │ │ └── ConsumerTest.java │ │ │ ├── test_1 │ │ │ ├── package-info.java │ │ │ ├── ProviderTest.java │ │ │ └── ConsumerTest.java │ │ │ ├── test_6 │ │ │ ├── package-info.java │ │ │ ├── HelloService.java │ │ │ ├── ProviderTest_1.java │ │ │ ├── ProviderTest_2.java │ │ │ ├── ProviderTest_3.java │ │ │ └── ConsumerTest.java │ │ │ ├── test_2 │ │ │ ├── package-info.java │ │ │ ├── HelloService.java │ │ │ ├── ProviderTest.java │ │ │ └── ConsumerTest.java │ │ │ ├── test_5 │ │ │ ├── package-info.java │ │ │ ├── HelloService.java │ │ │ ├── HelloServiceFlowControllerImpl.java │ │ │ ├── ProviderTest.java │ │ │ └── ConsumerTest.java │ │ │ ├── test_3 │ │ │ ├── HelloService.java │ │ │ ├── package-info.java │ │ │ ├── ProviderTest.java │ │ │ ├── ConsumerTest.java │ │ │ └── MonitorTest.java │ │ │ └── test_4 │ │ │ ├── HelloService.java │ │ │ ├── package-info.java │ │ │ ├── ProviderTest.java │ │ │ └── ConsumerTest.java │ │ └── resources │ │ ├── logback.xml │ │ ├── spring-provider.xml │ │ └── spring-consumer.xml └── pom.xml ├── laopopo-registry-default ├── src │ ├── main │ │ └── java │ │ │ └── org │ │ │ └── laopopo │ │ │ └── base │ │ │ └── registry │ │ │ ├── package-info.java │ │ │ ├── model │ │ │ ├── ReviewRecord.java │ │ │ └── RegistryPersistRecord.java │ │ │ ├── RegistryProviderServer.java │ │ │ ├── RegistryServerConfig.java │ │ │ ├── DefaultRegistryProcessor.java │ │ │ └── DefaultRegistryChannelInactiveProcessor.java │ └── test │ │ └── resources │ │ └── logback.xml └── pom.xml ├── laopopo-registry ├── src │ └── main │ │ └── java │ │ └── org │ │ └── laopopo │ │ └── registry │ │ └── RegistryServer.java └── pom.xml ├── laopopo-monitor ├── src │ └── main │ │ └── java │ │ └── org │ │ └── laopopo │ │ └── monitor │ │ ├── MonitorNode.java │ │ └── MonitorConfig.java └── pom.xml ├── laopopo-remoting ├── src │ └── main │ │ └── java │ │ └── org │ │ └── laopopo │ │ └── remoting │ │ ├── model │ │ ├── NettyRpcRequestProcessor.java │ │ ├── NettyRequestProcessor.java │ │ ├── ByteHolder.java │ │ ├── NettyChannelInactiveProcessor.java │ │ ├── Heartbeats.java │ │ └── RemotingResponse.java │ │ ├── watcher │ │ └── ChannelHandlerHolder.java │ │ ├── InvokeCallback.java │ │ ├── RPCHook.java │ │ ├── netty │ │ ├── BaseRemotingService.java │ │ ├── idle │ │ │ ├── AcceptorIdleStateTrigger.java │ │ │ └── ConnectorIdleStateTrigger.java │ │ ├── RemotingServer.java │ │ ├── encode │ │ │ └── RemotingTransporterEncoder.java │ │ ├── NettyServerConfig.java │ │ ├── RemotingClient.java │ │ └── decode │ │ │ └── RemotingTransporterDecoder.java │ │ └── ConnectionUtils.java └── pom.xml ├── laopopo-client ├── src │ ├── main │ │ └── java │ │ │ └── org │ │ │ └── laopopo │ │ │ └── client │ │ │ ├── provider │ │ │ ├── interceptor │ │ │ │ ├── ProviderInterceptor.java │ │ │ │ └── ProviderProxyHandler.java │ │ │ ├── ServiceWrapperWorker.java │ │ │ ├── model │ │ │ │ └── DefaultProviderInactiveProcessor.java │ │ │ ├── ServiceProviderContainer.java │ │ │ ├── DefaultProviderRPCProcessor.java │ │ │ ├── DefaultProviderRegistryProcessor.java │ │ │ ├── Provider.java │ │ │ └── flow │ │ │ │ └── control │ │ │ │ └── ServiceFlowController.java │ │ │ ├── annotation │ │ │ ├── RPConsumer.java │ │ │ └── RPCService.java │ │ │ ├── consumer │ │ │ ├── NotifyListener.java │ │ │ ├── ConsumerConfig.java │ │ │ └── DefaultConsumerRegistryProcessor.java │ │ │ └── metrics │ │ │ ├── Meter.java │ │ │ └── ServiceMeterManager.java │ └── test │ │ └── resources │ │ └── logback.xml └── pom.xml ├── laopopo-serialization ├── laopopo-serialization-api │ └── pom.xml └── pom.xml ├── README.md └── laopopo-spring-support ├── pom.xml └── src └── main └── java └── org └── laopopo └── spring └── support └── LaopopoSpringProviderBean.java /laopopo-console/src/main/resources/rpc.properties: -------------------------------------------------------------------------------- 1 | registryAddress = 127.0.0.1: -------------------------------------------------------------------------------- /laopopo-common/src/main/resources/META-INF/services/org.laopopo.common.serialization.Serializer: -------------------------------------------------------------------------------- 1 | org.laopopo.common.serialization.proto.ProtoStuffSerializer -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/demo/service/ByeService.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.demo.service; 2 | 3 | public interface ByeService { 4 | 5 | String sayBye(String str); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /laopopo-console/src/main/webapp/resources/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BazingaLyn/laopopo-rpc/HEAD/laopopo-console/src/main/webapp/resources/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /laopopo-console/src/main/webapp/resources/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BazingaLyn/laopopo-rpc/HEAD/laopopo-console/src/main/webapp/resources/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /laopopo-console/src/main/webapp/resources/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BazingaLyn/laopopo-rpc/HEAD/laopopo-console/src/main/webapp/resources/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/rpc/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.common.rpc; -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/loadbalance/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.common.loadbalance; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/benchmark/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 性能测试 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.benchmark; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/compress/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 压缩性能对比 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.compress; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/netty/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description netty 连接测试工具 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.netty; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/spring/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 对spring的支持 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.spring; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/other/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 对一些基本java概念的测试 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.other; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/persist/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 持久化数据到硬盘的测试 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.persist; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/serializer/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 序列化的测试 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.serializer; -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/exception/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 所有的异常包 7 | * @time 2016年8月15日 8 | * @modifytime 9 | */ 10 | package org.laopopo.common.exception; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/flow/controller/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.flow.controller; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/netty/example_1/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.netty.example_1; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_7/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 负载均衡的测试 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.generic.test_7; -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/exception/rpc/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description rpc调用的异常 7 | * @time 2016年8月23日 8 | * @modifytime 9 | */ 10 | package org.laopopo.common.exception.rpc; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_1/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 测试RPC的基本流程 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.generic.test_1; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_6/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 注册中心的负载均衡的测试 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.generic.test_6; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/benchmark/big_request/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 大的请求包 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.benchmark.big_request; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_2/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description consumer端接口调用 测试 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.generic.test_2; -------------------------------------------------------------------------------- /laopopo-registry-default/src/main/java/org/laopopo/base/registry/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 默认的注册中心,基于内存实现,所有的数据存储在内存内,不做持久化的操作 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.base.registry; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/benchmark/big_request_compress/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | package org.laopopo.example.benchmark.big_request_compress; -------------------------------------------------------------------------------- /laopopo-registry/src/main/java/org/laopopo/registry/RegistryServer.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.registry; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 注册中心 7 | * @time 8 | * @modifytime 2016年10月19日 9 | */ 10 | public interface RegistryServer { 11 | 12 | void start(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /laopopo-monitor/src/main/java/org/laopopo/monitor/MonitorNode.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.monitor; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 监控中心,单节点,宕机不影响主体业务处理 7 | * @time 2016年8月15日 8 | * @modifytime 9 | */ 10 | public interface MonitorNode { 11 | 12 | void start(); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/spring/HelloService.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.spring; 2 | 3 | import org.laopopo.client.annotation.RPConsumer; 4 | 5 | public interface HelloService { 6 | 7 | @RPConsumer(serviceName="LAOPOPO.TEST.SAYHELLO") 8 | String sayHello(String str); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/demo/service/HelloSerivce.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.demo.service; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | public interface HelloSerivce { 11 | 12 | String sayHello(String str); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/demo/service/HelloServiceMock.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.demo.service; 2 | 3 | public class HelloServiceMock implements HelloSerivce { 4 | 5 | @Override 6 | public String sayHello(String str) { 7 | 8 | //直接给出默认的返回值 9 | return "hello"; 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_5/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 测试单位时间的限流是否生效 7 | * 8 | * 先运行ProviderTest 9 | * 再运行ConsumerTest 10 | * @time 2016年9月14日 11 | * @modifytime 12 | */ 13 | package org.laopopo.example.generic.test_5; -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_2/HelloService.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_2; 2 | 3 | import org.laopopo.client.annotation.RPConsumer; 4 | 5 | public interface HelloService { 6 | 7 | @RPConsumer(serviceName="LAOPOPO.TEST.SAYHELLO") 8 | String sayHello(String str); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_3/HelloService.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_3; 2 | 3 | import org.laopopo.client.annotation.RPConsumer; 4 | 5 | public interface HelloService { 6 | 7 | @RPConsumer(serviceName="LAOPOPO.TEST.SAYHELLO") 8 | String sayHello(String str); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_4/HelloService.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_4; 2 | 3 | import org.laopopo.client.annotation.RPConsumer; 4 | 5 | public interface HelloService { 6 | 7 | @RPConsumer(serviceName="LAOPOPO.TEST.SAYHELLO") 8 | String sayHello(String str); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_5/HelloService.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_5; 2 | 3 | import org.laopopo.client.annotation.RPConsumer; 4 | 5 | public interface HelloService { 6 | 7 | @RPConsumer(serviceName="LAOPOPO.TEST.SAYHELLO") 8 | String sayHello(String str); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_6/HelloService.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_6; 2 | 3 | import org.laopopo.client.annotation.RPConsumer; 4 | 5 | public interface HelloService { 6 | 7 | @RPConsumer(serviceName="LAOPOPO.TEST.SAYHELLO") 8 | String sayHello(String str); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_7/HelloService.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_7; 2 | 3 | import org.laopopo.client.annotation.RPConsumer; 4 | 5 | public interface HelloService { 6 | 7 | @RPConsumer(serviceName="LAOPOPO.TEST.SAYHELLO") 8 | String sayHello(String str); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/model/NettyRpcRequestProcessor.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.model; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | 5 | public interface NettyRpcRequestProcessor { 6 | 7 | void processRPCRequest(ChannelHandlerContext ctx, RemotingTransporter request); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /laopopo-console/src/main/java/org/laopopo/console/info/kaleidoscope/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description 各种信息的采集的万花筒 含有一个netty Client端,去连接monitor和registry 7 | * 还有一个定时任务群,去定时采集更新各种数据 8 | * @time 2016年8月17日 9 | * @modifytime 10 | */ 11 | package org.laopopo.console.info.kaleidoscope; -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/watcher/ChannelHandlerHolder.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.watcher; 2 | 3 | import io.netty.channel.ChannelHandler; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * 9 | * @time 10 | */ 11 | public interface ChannelHandlerHolder { 12 | 13 | ChannelHandler[] handlers(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /laopopo-console/src/main/webapp/resources/css/starter-template.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | } 4 | .starter-template { 5 | padding: 40px 15px; 6 | text-align: center; 7 | } 8 | 9 | footer { 10 | color: #777; 11 | padding: 20px 0; 12 | border-top: 1px solid #e5e5e5; 13 | margin-top: 70px; 14 | bottom:0px; 15 | left:0px; 16 | } 17 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_4/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description consumer和provider直连的测试, 7 | * 1)假如注册中心宕机的情况下,consumer可以直接拿着IP+端口号直接调用服务 8 | * 2)或者直接不将服务注册到注册中心,服务消费者和服务提供者直连调用 9 | * @time 2016年9月13日 10 | * @modifytime 11 | */ 12 | package org.laopopo.example.generic.test_4; -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/model/NettyRequestProcessor.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.model; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | 5 | public interface NettyRequestProcessor { 6 | 7 | RemotingTransporter processRequest(ChannelHandlerContext ctx, RemotingTransporter request) 8 | throws Exception; 9 | 10 | } 11 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/loadbalance/LoadBalanceStrategy.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.loadbalance; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 负载均衡的访问策略 7 | * @time 2016年8月31日 8 | * @modifytime 9 | */ 10 | public enum LoadBalanceStrategy { 11 | 12 | RANDOM, //随机 13 | WEIGHTINGRANDOM, //加权随机 14 | ROUNDROBIN, //轮询 15 | 16 | } 17 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_3/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author BazingaLyn 6 | * @description consumer端接口调用 测试 增加monitor端的运行基本测试 7 | * 1) 先运行RegistryTest 8 | * 2) 再运行MonitorTest 9 | * 3) 再运行ProviderTest 10 | * 4) 最后运行ConsumerTest 11 | * @time 12 | * @modifytime 13 | */ 14 | package org.laopopo.example.generic.test_3; -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/rpc/ServiceReviewState.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.rpc; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 服务审核状态 7 | * @time 2016年8月17日 8 | * @modifytime 2016年8月22日 9 | */ 10 | public enum ServiceReviewState { 11 | 12 | HAS_NOT_REVIEWED, //未审核 13 | PASS_REVIEW, //通过审核 14 | NOT_PASS_REVIEW, //未通过审核 15 | FORBIDDEN //禁用 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/InvokeCallback.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting; 2 | 3 | import org.laopopo.remoting.model.RemotingResponse; 4 | 5 | 6 | /** 7 | * 8 | * @author BazingaLyn 9 | * @description 远程调用之后的回调函数 10 | * @time 2016年8月10日11:06:40 11 | * @modifytime 12 | */ 13 | public interface InvokeCallback { 14 | 15 | void operationComplete(final RemotingResponse remotingResponse); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/provider/interceptor/ProviderInterceptor.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.provider.interceptor; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | public interface ProviderInterceptor { 11 | 12 | void beforeInvoke(String methodName, Object[] args); 13 | 14 | void afterInvoke(String methodName, Object[] args, Object result); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/spi/BaseServiceLoader.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.spi; 2 | 3 | import java.util.ServiceLoader; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * @description SPI loader 9 | * @time 2016年8月11日 10 | * @modifytime 11 | */ 12 | public final class BaseServiceLoader { 13 | 14 | public static S load(Class serviceClass) { 15 | return ServiceLoader.load(serviceClass).iterator().next(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/transport/body/CommonCustomBody.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.transport.body; 2 | 3 | import org.laopopo.common.exception.remoting.RemotingCommmonCustomException; 4 | 5 | 6 | 7 | /** 8 | * 9 | * @author BazingaLyn 10 | * @description 网络传输对象的主体对象 11 | * @time 2016年8月10日 12 | * @modifytime 13 | */ 14 | public interface CommonCustomBody { 15 | 16 | void checkFields() throws RemotingCommmonCustomException; 17 | } 18 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/demo/service/ByeServiceImpl.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.demo.service; 2 | 3 | import org.laopopo.client.annotation.RPCService; 4 | 5 | public class ByeServiceImpl implements ByeService { 6 | 7 | @Override 8 | @RPCService(responsibilityName="fly100%",serviceName ="LAOPOPO.TEST.SAYBYE",isVIPService = true,isSupportDegradeService = false) 9 | public String sayBye(String str) { 10 | return "bye " + str; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/demo/service/HelloService_1.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.demo.service; 2 | 3 | import org.laopopo.client.annotation.RPCService; 4 | import org.laopopo.example.demo.service.HelloSerivce; 5 | 6 | public class HelloService_1 implements HelloSerivce { 7 | 8 | @Override 9 | @RPCService(responsibilityName = "xiaoy", serviceName = "LAOPOPO.TEST.SAYHELLO", weight = 5) 10 | public String sayHello(String str) { 11 | return "hello_1"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/demo/service/HelloService_2.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.demo.service; 2 | 3 | import org.laopopo.client.annotation.RPCService; 4 | import org.laopopo.example.demo.service.HelloSerivce; 5 | 6 | public class HelloService_2 implements HelloSerivce { 7 | 8 | @Override 9 | @RPCService(responsibilityName = "xiaoy", serviceName = "LAOPOPO.TEST.SAYHELLO", weight = 90) 10 | public String sayHello(String str) { 11 | return "hello_2"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/demo/service/HelloService_3.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.demo.service; 2 | 3 | import org.laopopo.client.annotation.RPCService; 4 | import org.laopopo.example.demo.service.HelloSerivce; 5 | 6 | public class HelloService_3 implements HelloSerivce { 7 | 8 | @Override 9 | @RPCService(responsibilityName = "xiaoy", serviceName = "LAOPOPO.TEST.SAYHELLO", weight = 5) 10 | public String sayHello(String str) { 11 | return "hello_3"; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/rpc/ManagerServiceRequestType.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.rpc; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | public enum ManagerServiceRequestType { 11 | 12 | REVIEW, //审核某个地址的服务 发送的信息含服务名和审核状态和提供该服务的地址就ok,只修改该地址的审核状态 13 | DEGRADE, //降级或者还原某个地址的服务 14 | MODIFY_WEIGHT, //修改某个地址某个服务的权重 15 | MODIFY_LOADBALANCE, //修改某个服务的访问策略 16 | METRICS; //统计服务 17 | 18 | } 19 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/spring/SpringProviderTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.spring; 2 | 3 | import org.springframework.context.support.ClassPathXmlApplicationContext; 4 | 5 | 6 | /** 7 | * 8 | * @author BazingaLyn 9 | * @description 10 | * @time 2016年10月18日 11 | * @modifytime 12 | */ 13 | public class SpringProviderTest { 14 | 15 | public static void main(String[] args) { 16 | new ClassPathXmlApplicationContext("classpath:spring-provider.xml"); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/demo/service/HelloServiceBenchmark.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.demo.service; 2 | 3 | import org.laopopo.client.annotation.RPCService; 4 | 5 | public class HelloServiceBenchmark implements HelloSerivce { 6 | 7 | @Override 8 | @RPCService(responsibilityName="xiaoy", 9 | serviceName="LAOPOPO.TEST.SAYHELLO", 10 | connCount = 4, 11 | isFlowController = false, 12 | degradeServiceDesc="默认返回hello") 13 | public String sayHello(String str) { 14 | return str; 15 | } 16 | 17 | 18 | } 19 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_5/HelloServiceFlowControllerImpl.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_5; 2 | 3 | import org.laopopo.client.annotation.RPCService; 4 | import org.laopopo.example.demo.service.HelloSerivce; 5 | 6 | public class HelloServiceFlowControllerImpl implements HelloSerivce { 7 | 8 | @Override 9 | @RPCService(responsibilityName="xiaoy",serviceName="LAOPOPO.TEST.SAYHELLO",maxCallCountInMinute = 40) 10 | public String sayHello(String str) { 11 | return "hello "+ str; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/model/ByteHolder.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.model; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 7 | * @time 2016年8月9日 8 | * @modifytime 9 | */ 10 | public class ByteHolder { 11 | 12 | private transient byte[] bytes; 13 | 14 | public byte[] bytes() { 15 | return bytes; 16 | } 17 | 18 | public void bytes(byte[] bytes) { 19 | this.bytes = bytes; 20 | } 21 | 22 | public int size() { 23 | return bytes == null ? 0 : bytes.length; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/serialization/SerializerHolder.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.serialization; 2 | 3 | import org.laopopo.common.spi.BaseServiceLoader; 4 | 5 | 6 | /** 7 | * 8 | * @author BazingaLyn 9 | * @description 序列化的入口,基于SPI方式 10 | * @time 2016年8月12日 11 | * @modifytime 12 | */ 13 | public final class SerializerHolder { 14 | 15 | // SPI 16 | private static final Serializer serializer = BaseServiceLoader.load(Serializer.class); 17 | 18 | public static Serializer serializerImpl() { 19 | return serializer; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/serialization/Serializer.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.serialization; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 序列化接口 7 | * @time 2016年8月12日 8 | * @modifytime 9 | */ 10 | public interface Serializer { 11 | 12 | /** 13 | * 将对象序列化成byte[] 14 | * @param obj 15 | * @return 16 | */ 17 | byte[] writeObject(T obj); 18 | 19 | /** 20 | * 将byte数组反序列成对象 21 | * @param bytes 22 | * @param clazz 23 | * @return 24 | */ 25 | T readObject(byte[] bytes, Class clazz); 26 | } 27 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/RPCHook.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting; 2 | 3 | import org.laopopo.remoting.model.RemotingTransporter; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * @description RPC的回调钩子,在发送请求和接收请求的时候触发,这样做事增加程序的健壮性和灵活性 9 | * @time 2016年8月10日14:40:47 10 | * @modifytime 11 | */ 12 | public interface RPCHook { 13 | 14 | void doBeforeRequest(final String remoteAddr, final RemotingTransporter request); 15 | 16 | void doAfterResponse(final String remoteAddr, final RemotingTransporter request,final RemotingTransporter response); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/exception/remoting/RemotingException.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.exception.remoting; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | public class RemotingException extends Exception { 11 | 12 | 13 | private static final long serialVersionUID = -298481855025395391L; 14 | 15 | 16 | public RemotingException(String message) { 17 | super(message); 18 | } 19 | 20 | 21 | public RemotingException(String message, Throwable cause) { 22 | super(message, cause); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/annotation/RPConsumer.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * 11 | * @author BazingaLyn 12 | * @description 13 | * @time 14 | * @modifytime 15 | */ 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Target({ ElementType.METHOD }) 18 | @Documented 19 | public @interface RPConsumer { 20 | 21 | public String serviceName() default "";//服务名 22 | 23 | } 24 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/exception/remoting/RemotingNoSighException.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.exception.remoting; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | public class RemotingNoSighException extends RemotingException { 11 | 12 | private static final long serialVersionUID = -1661779813708564404L; 13 | 14 | 15 | public RemotingNoSighException(String message) { 16 | super(message, null); 17 | } 18 | 19 | 20 | public RemotingNoSighException(String message, Throwable cause) { 21 | super(message, cause); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /laopopo-serialization/laopopo-serialization-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.bazinga 7 | laopopo-serialization 8 | 1.0.0 9 | 10 | laopopo-serialization-api 11 | laopopo-serialization-api 12 | http://maven.apache.org 13 | 14 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/exception/remoting/RemotingContextException.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.exception.remoting; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | public class RemotingContextException extends RemotingException { 11 | 12 | private static final long serialVersionUID = -6365082302690352325L; 13 | 14 | 15 | public RemotingContextException(String message) { 16 | super(message, null); 17 | } 18 | 19 | 20 | public RemotingContextException(String message, Throwable cause) { 21 | super(message, cause); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/provider/ServiceWrapperWorker.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.provider; 2 | 3 | import java.util.List; 4 | 5 | import org.laopopo.client.provider.interceptor.ProviderProxyHandler; 6 | import org.laopopo.client.provider.model.ServiceWrapper; 7 | 8 | 9 | /** 10 | * 11 | * @author BazingaLyn 12 | * @description 13 | * @time 14 | * @modifytime 15 | */ 16 | public interface ServiceWrapperWorker { 17 | 18 | ServiceWrapperWorker provider(Object serviceProvider); 19 | 20 | ServiceWrapperWorker provider(ProviderProxyHandler proxyHandler,Object serviceProvider); 21 | 22 | List create(); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/exception/remoting/RemotingCommmonCustomException.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.exception.remoting; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | public class RemotingCommmonCustomException extends RemotingException { 11 | 12 | 13 | private static final long serialVersionUID = 1546308581637799641L; 14 | 15 | 16 | public RemotingCommmonCustomException(String message) { 17 | super(message, null); 18 | } 19 | 20 | 21 | public RemotingCommmonCustomException(String message, Throwable cause) { 22 | super(message, cause); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/exception/remoting/RemotingSendRequestException.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.exception.remoting; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | public class RemotingSendRequestException extends RemotingException { 11 | private static final long serialVersionUID = 5391285827332471674L; 12 | 13 | 14 | public RemotingSendRequestException(String addr) { 15 | this(addr, null); 16 | } 17 | 18 | 19 | public RemotingSendRequestException(String addr, Throwable cause) { 20 | super("send request to <" + addr + "> failed", cause); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/utils/NativeSupport.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.utils; 2 | 3 | public final class NativeSupport { 4 | 5 | private static final boolean SUPPORT_NATIVE_ET; 6 | 7 | static { 8 | boolean epoll; 9 | try { 10 | Class.forName("io.netty.channel.epoll.Native"); 11 | epoll = true; 12 | } catch (Throwable e) { 13 | epoll = false; 14 | } 15 | SUPPORT_NATIVE_ET = epoll; 16 | } 17 | 18 | /** 19 | * The native socket transport for Linux using JNI. 20 | */ 21 | public static boolean isSupportNativeET() { 22 | return SUPPORT_NATIVE_ET; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/model/NettyChannelInactiveProcessor.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.model; 2 | 3 | import org.laopopo.common.exception.remoting.RemotingSendRequestException; 4 | import org.laopopo.common.exception.remoting.RemotingTimeoutException; 5 | 6 | import io.netty.channel.ChannelHandlerContext; 7 | 8 | /** 9 | * 10 | * @author BazingaLyn 11 | * @description 处理channel关闭或者inactive的状态的时候的改变 12 | * @time 2016年8月15日 13 | * @modifytime 14 | */ 15 | public interface NettyChannelInactiveProcessor { 16 | 17 | 18 | void processChannelInactive(ChannelHandlerContext ctx) throws RemotingSendRequestException, RemotingTimeoutException, InterruptedException; 19 | } 20 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_7/ProviderTest_3.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_7; 2 | 3 | import org.laopopo.client.provider.DefaultProvider; 4 | import org.laopopo.common.exception.remoting.RemotingException; 5 | import org.laopopo.example.demo.service.HelloService_3; 6 | 7 | public class ProviderTest_3 { 8 | 9 | public static void main(String[] args) throws InterruptedException, RemotingException { 10 | 11 | DefaultProvider defaultProvider = new DefaultProvider(); 12 | 13 | defaultProvider.serviceListenPort(7001) // 暴露服务的地址 14 | .publishService(new HelloService_3()) // 暴露的服务 15 | .start(); // 启动服务 16 | 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_7/ProviderTest_1.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_7; 2 | 3 | import org.laopopo.client.provider.DefaultProvider; 4 | import org.laopopo.common.exception.remoting.RemotingException; 5 | import org.laopopo.example.demo.service.HelloService_1; 6 | 7 | public class ProviderTest_1 { 8 | 9 | public static void main(String[] args) throws InterruptedException, RemotingException { 10 | 11 | DefaultProvider defaultProvider = new DefaultProvider(); 12 | 13 | defaultProvider.serviceListenPort(9001) // 暴露服务的地址 14 | .publishService(new HelloService_1()) // 暴露的服务 15 | .start(); // 启动服务 16 | 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_7/ProviderTest_2.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_7; 2 | 3 | import org.laopopo.client.provider.DefaultProvider; 4 | import org.laopopo.common.exception.remoting.RemotingException; 5 | import org.laopopo.example.demo.service.HelloService_2; 6 | 7 | public class ProviderTest_2 { 8 | 9 | public static void main(String[] args) throws InterruptedException, RemotingException { 10 | 11 | DefaultProvider defaultProvider = new DefaultProvider(); 12 | 13 | defaultProvider.serviceListenPort(8001) // 暴露服务的地址 14 | .publishService(new HelloService_2()) // 暴露的服务 15 | .start(); // 启动服务 16 | 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/netty/BaseRemotingService.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.netty; 2 | 3 | import org.laopopo.remoting.RPCHook; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * @description Netty网络通讯端Client端和Server端都需要实现的方法集合 9 | * @time 2016年8月10日 10 | * @modifytime 11 | */ 12 | public interface BaseRemotingService { 13 | 14 | /** 15 | * Netty的一些参数的初始化 16 | */ 17 | void init(); 18 | 19 | /** 20 | * 启动Netty方法 21 | */ 22 | void start(); 23 | 24 | /** 25 | * 关闭Netty C/S 实例 26 | */ 27 | void shutdown(); 28 | 29 | /** 30 | * 注入钩子,Netty在处理的过程中可以嵌入一些方法,增加代码的灵活性 31 | * @param rpcHook 32 | */ 33 | void registerRPCHook(RPCHook rpcHook); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /laopopo-serialization/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | com.bazinga 8 | laopopo 9 | 1.0.0 10 | 11 | 12 | laopopo-serialization 13 | laopopo-serialization 14 | http://maven.apache.org 15 | pom 16 | 17 | 18 | laopopo-serialization-api 19 | 20 | 21 | -------------------------------------------------------------------------------- /laopopo-registry/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.bazinga 8 | laopopo 9 | 1.0.0 10 | 11 | laopopo-registry 12 | laopopo-registry 13 | http://maven.apache.org 14 | 15 | 16 | 17 | ${project.groupId} 18 | laopopo-common 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_5/ProviderTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_5; 2 | 3 | import org.laopopo.client.provider.DefaultProvider; 4 | import org.laopopo.common.exception.remoting.RemotingException; 5 | 6 | /** 7 | * 8 | * @author BazingaLyn 9 | * @description 测试单位时间的限流 10 | * @time 2016年9月14日 11 | * @modifytime 12 | */ 13 | public class ProviderTest { 14 | 15 | public static void main(String[] args) throws InterruptedException, RemotingException { 16 | 17 | DefaultProvider defaultProvider = new DefaultProvider(); 18 | 19 | defaultProvider.serviceListenPort(8899) // 暴露服务的地址 20 | .publishService(new HelloServiceFlowControllerImpl()) // 暴露的服务 21 | .start(); // 启动服务 22 | 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_4/ProviderTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_4; 2 | 3 | import org.laopopo.client.provider.DefaultProvider; 4 | import org.laopopo.common.exception.remoting.RemotingException; 5 | import org.laopopo.example.demo.service.ByeServiceImpl; 6 | import org.laopopo.example.demo.service.HelloSerivceImpl; 7 | 8 | public class ProviderTest { 9 | 10 | public static void main(String[] args) throws InterruptedException, RemotingException { 11 | 12 | DefaultProvider defaultProvider = new DefaultProvider(); 13 | 14 | defaultProvider.serviceListenPort(8899) // 暴露服务的地址 15 | .publishService(new HelloSerivceImpl(), new ByeServiceImpl()) // 暴露的服务 16 | .start(); // 启动服务 17 | 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/persist/Teacher.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.persist; 2 | 3 | import java.io.Serializable; 4 | 5 | public class Teacher implements Serializable { 6 | 7 | 8 | /** 9 | * 10 | */ 11 | private static final long serialVersionUID = -7057437939312498114L; 12 | 13 | private Integer id; 14 | 15 | private String name; 16 | 17 | public Teacher(Integer id, String name) { 18 | super(); 19 | this.id = id; 20 | this.name = name; 21 | } 22 | 23 | public Integer getId() { 24 | return id; 25 | } 26 | 27 | public void setId(Integer id) { 28 | this.id = id; 29 | } 30 | 31 | public String getName() { 32 | return name; 33 | } 34 | 35 | public void setName(String name) { 36 | this.name = name; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/transport/body/SubscribeRequestCustomBody.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.transport.body; 2 | 3 | import org.laopopo.common.exception.remoting.RemotingCommmonCustomException; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * @description 消费者订阅服务的主题消息,这边做的相对简单,只要有唯一的名字控制就好 9 | * @time 2016年8月29日 10 | * @modifytime 11 | */ 12 | public class SubscribeRequestCustomBody implements CommonCustomBody { 13 | 14 | private String serviceName; 15 | 16 | public String getServiceName() { 17 | return serviceName; 18 | } 19 | 20 | public void setServiceName(String serviceName) { 21 | this.serviceName = serviceName; 22 | } 23 | 24 | @Override 25 | public void checkFields() throws RemotingCommmonCustomException { 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/demo/service/HelloSerivceImpl.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.demo.service; 2 | 3 | import org.laopopo.client.annotation.RPCService; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * @description Demo 9 | * @time 2016年8月19日 10 | * @modifytime 11 | */ 12 | public class HelloSerivceImpl implements HelloSerivce { 13 | 14 | @Override 15 | @RPCService(responsibilityName="xiaoy", 16 | serviceName="LAOPOPO.TEST.SAYHELLO", 17 | isVIPService = false, 18 | isSupportDegradeService = true, 19 | degradeServicePath="org.laopopo.example.demo.service.HelloServiceMock", 20 | degradeServiceDesc="默认返回hello") 21 | public String sayHello(String str) { 22 | 23 | //真实逻辑可能涉及到查库 24 | return "hello "+ str; 25 | 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/transport/body/MetricsCustomBody.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.transport.body; 2 | 3 | import java.util.List; 4 | 5 | import org.laopopo.common.exception.remoting.RemotingCommmonCustomException; 6 | import org.laopopo.common.metrics.ServiceMetrics; 7 | 8 | public class MetricsCustomBody implements CommonCustomBody { 9 | 10 | private List serviceMetricses; 11 | 12 | @Override 13 | public void checkFields() throws RemotingCommmonCustomException { 14 | } 15 | 16 | public List getServiceMetricses() { 17 | return serviceMetricses; 18 | } 19 | 20 | public void setServiceMetricses(List serviceMetricses) { 21 | this.serviceMetricses = serviceMetricses; 22 | } 23 | 24 | 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /laopopo-registry-default/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] [%logger{0}] - %msg%n 9 | 10 | 11 | 12 | 13 | 14 | 65536 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/exception/rpc/NoServiceException.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.exception.rpc; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | public class NoServiceException extends RuntimeException { 11 | 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = -7743840667451216980L; 16 | 17 | public NoServiceException() { 18 | super(); 19 | } 20 | 21 | public NoServiceException(String message) { 22 | super(message); 23 | } 24 | 25 | public NoServiceException(String message, Throwable cause) { 26 | super(message, cause); 27 | } 28 | 29 | public NoServiceException(Throwable cause) { 30 | super(cause); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ###Laopopo-RPC 2 | 3 | laopopo-rpc 是一个相对比较完整的RPC框架 4 | 5 | ------------------------------------------------------------------------------------------------------- 6 | 7 | 8 | 9 | 10 | 基本功能都完成了,写这个相对比较完整的Demo的意义并不是做一个多优秀的RPC框架,能力有限,不过正是因为能力有限,才会去尝试去写, 11 | 写完才会有提高,才会有收获,以前觉得RPC很神秘,看看别人的源代码,知道了一些基本原理,开拓了自己的视野,闲暇的时候写写代码, 12 | 增强自己的能力,这就是写个DEMO的意义吧 13 | 14 | 中间有很多借鉴别人的地方,有很多地方肯定也是有缺漏的,也是这里面肯定是bug的,不过,可能我没有发现,能改的是缺点,不能改的是弱点, 15 | 所以我暂没有发现的bug,也是是我能力的不足吧 16 | 17 | 还是说说这个Laopopo RPC吧,这个RPC Demo整体设计的思路来自于RocketMQ,一些业务逻辑实现借鉴于Jupiter,完成的功能也算比较齐全吧 18 | 19 | 心跳,重连,限流,降级什么一些基本的RPC的组件都还是齐全的,不过还有一些不完善的地方,比如监控中心那边写的就是比较凌乱,最后导致console端 20 | 没有写完,希望以后有机会把这块重新写下 21 | 22 | 关于性能,我没有去仔细去测过,性能测试模块,我就是用自己公司的PC去完成的,Server/Client都是在同一个机器上运行的,结果自然是相对偏低 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/exception/rpc/ProviderHandlerException.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.exception.rpc; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 服务提供者端处理消费者的请求的时候,出现的异常 7 | * @time 2016年9月14日 8 | * @modifytime 9 | */ 10 | public class ProviderHandlerException extends RuntimeException { 11 | 12 | /** 13 | * 14 | */ 15 | private static final long serialVersionUID = -5212501638591073686L; 16 | 17 | public ProviderHandlerException() {} 18 | 19 | public ProviderHandlerException(String message) { 20 | super(message); 21 | } 22 | 23 | public ProviderHandlerException(String message, Throwable cause) { 24 | super(message, cause); 25 | } 26 | 27 | public ProviderHandlerException(Throwable cause) { 28 | super(cause); 29 | } 30 | 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/spring/SpringConsumerTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.spring; 2 | 3 | import org.springframework.context.ApplicationContext; 4 | import org.springframework.context.support.ClassPathXmlApplicationContext; 5 | 6 | /** 7 | * 8 | * @author BazingaLyn 9 | * @description 10 | * @time 2016年10月18日 11 | * @modifytime 12 | */ 13 | public class SpringConsumerTest { 14 | 15 | public static void main(String[] args) { 16 | ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:spring-consumer.xml"); 17 | HelloService service = ctx.getBean(HelloService.class); 18 | try { 19 | String result1 = service.sayHello("Lyncc"); 20 | System.out.println(result1); 21 | } catch (Exception e) { 22 | e.printStackTrace(); 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/consumer/NotifyListener.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.consumer; 2 | 3 | import org.laopopo.common.rpc.RegisterMeta; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * @description 当consumer从register注册中心获取到订阅信息之后返回的结果集,这边之所以做的相对复杂的原因就是因为 9 | * 从注册中心拿到提供者的地址之后,netty去连接的时候是异步的的,ChannelFuture.channel这边是异步的,也就是说你不知道啥时候能够 10 | * ChannelFuture.isSuccess()== true,除非在后面增加一个Listener,档期operationSuccess的时候才会周知用户,所有的动作初始化完毕了,可以直接调用 11 | * @time 2016年8月26日 12 | * @modifytime 13 | */ 14 | public interface NotifyListener { 15 | 16 | /** 17 | * 接收到register返回的RegisterMeta的时候,去连接provider端 18 | * @param registerMeta 19 | * @param event 20 | */ 21 | void notify(RegisterMeta registerMeta, NotifyEvent event); 22 | 23 | enum NotifyEvent { 24 | CHILD_ADDED, 25 | CHILD_REMOVED 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/exception/remoting/RemotingTimeoutException.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.exception.remoting; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | public class RemotingTimeoutException extends RemotingException { 11 | 12 | private static final long serialVersionUID = 8752267201986569541L; 13 | 14 | 15 | public RemotingTimeoutException(String message) { 16 | super(message); 17 | } 18 | 19 | 20 | public RemotingTimeoutException(String addr, long timeoutMillis) { 21 | this(addr, timeoutMillis, null); 22 | } 23 | 24 | 25 | public RemotingTimeoutException(String addr, long timeoutMillis, Throwable cause) { 26 | super("wait response on the channel <" + addr + "> timeout, " + timeoutMillis + "(ms)", cause); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/serialization/fastjson/FastjsonSerializer.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.serialization.fastjson; 2 | 3 | import org.laopopo.common.serialization.Serializer; 4 | 5 | import com.alibaba.fastjson.JSON; 6 | import com.alibaba.fastjson.parser.Feature; 7 | import com.alibaba.fastjson.serializer.SerializerFeature; 8 | 9 | /** 10 | * 11 | * @author BazingaLyn 12 | * @description 使用fastjson序列化 13 | * 需要有无参构造函数 14 | * @time 2016年8月12日 15 | * @modifytime 16 | */ 17 | public class FastjsonSerializer implements Serializer { 18 | 19 | @Override 20 | public byte[] writeObject(T obj) { 21 | return JSON.toJSONBytes(obj, SerializerFeature.SortField); 22 | } 23 | 24 | @Override 25 | public T readObject(byte[] bytes, Class clazz) { 26 | return JSON.parseObject(bytes, clazz, Feature.SortFeidFastMatch); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/persist/Student.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.persist; 2 | 3 | public class Student { 4 | 5 | private Integer id; 6 | 7 | private String name; 8 | 9 | private int age; 10 | 11 | public Student() { 12 | // TODO Auto-generated constructor stub 13 | } 14 | 15 | public Student(Integer id, String name, int age) { 16 | super(); 17 | this.id = id; 18 | this.name = name; 19 | this.age = age; 20 | } 21 | 22 | public Integer getId() { 23 | return id; 24 | } 25 | 26 | public void setId(Integer id) { 27 | this.id = id; 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public void setName(String name) { 35 | this.name = name; 36 | } 37 | 38 | public int getAge() { 39 | return age; 40 | } 41 | 42 | public void setAge(int age) { 43 | this.age = age; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /laopopo-console/src/main/webapp/resources/js/locale/bootstrap-table-zh-CN.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * bootstrap-table - v1.11.0 - 2016-07-02 3 | * https://github.com/wenzhixin/bootstrap-table 4 | * Copyright (c) 2016 zhixin wen 5 | * Licensed MIT License 6 | */ 7 | !function(a){"use strict";a.fn.bootstrapTable.locales["zh-CN"]={formatLoadingMessage:function(){return"正在努力地加载数据中,请稍候……"},formatRecordsPerPage:function(a){return"每页显示 "+a+" 条记录"},formatShowingRows:function(a,b,c){return"显示第 "+a+" 到第 "+b+" 条记录,总共 "+c+" 条记录"},formatSearch:function(){return"搜索"},formatNoMatches:function(){return"没有找到匹配的记录"},formatPaginationSwitch:function(){return"隐藏/显示分页"},formatRefresh:function(){return"刷新"},formatToggle:function(){return"切换"},formatColumns:function(){return"列"},formatExport:function(){return"导出数据"},formatClearFilters:function(){return"清空过滤"}},a.extend(a.fn.bootstrapTable.defaults,a.fn.bootstrapTable.locales["zh-CN"])}(jQuery); -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/transport/body/OfflineNoticeCustomBody.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.transport.body; 2 | 3 | import org.laopopo.common.exception.remoting.RemotingCommmonCustomException; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * @description 下线通知的时候发送给consumer的主体 9 | * @time 2016年8月22日 10 | * @modifytime 11 | */ 12 | public class OfflineNoticeCustomBody implements CommonCustomBody { 13 | 14 | private int port; 15 | 16 | private String host; 17 | 18 | @Override 19 | public void checkFields() throws RemotingCommmonCustomException { 20 | } 21 | 22 | public int getPort() { 23 | return port; 24 | } 25 | 26 | public void setPort(int port) { 27 | this.port = port; 28 | } 29 | 30 | public String getHost() { 31 | return host; 32 | } 33 | 34 | public void setHost(String host) { 35 | this.host = host; 36 | } 37 | 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_6/ProviderTest_1.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_6; 2 | 3 | import org.laopopo.client.provider.DefaultProvider; 4 | import org.laopopo.common.exception.remoting.RemotingException; 5 | import org.laopopo.example.demo.service.HelloService_1; 6 | import org.laopopo.remoting.netty.NettyClientConfig; 7 | import org.laopopo.remoting.netty.NettyServerConfig; 8 | 9 | public class ProviderTest_1 { 10 | 11 | public static void main(String[] args) throws InterruptedException, RemotingException { 12 | 13 | DefaultProvider defaultProvider = new DefaultProvider(new NettyClientConfig(), new NettyServerConfig()); 14 | 15 | defaultProvider.registryAddress("127.0.0.1:18010") // 注册中心的地址 16 | .serviceListenPort(9001) // 暴露服务的端口 17 | .publishService(new HelloService_1()) // 暴露的服务 18 | .start(); // 启动服务 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_6/ProviderTest_2.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_6; 2 | 3 | import org.laopopo.client.provider.DefaultProvider; 4 | import org.laopopo.common.exception.remoting.RemotingException; 5 | import org.laopopo.example.demo.service.HelloService_2; 6 | import org.laopopo.remoting.netty.NettyClientConfig; 7 | import org.laopopo.remoting.netty.NettyServerConfig; 8 | 9 | public class ProviderTest_2 { 10 | 11 | public static void main(String[] args) throws InterruptedException, RemotingException { 12 | 13 | DefaultProvider defaultProvider = new DefaultProvider(new NettyClientConfig(), new NettyServerConfig()); 14 | 15 | defaultProvider.registryAddress("127.0.0.1:18010") // 注册中心的地址 16 | .serviceListenPort(8001) // 暴露服务的端口 17 | .publishService(new HelloService_2()) // 暴露的服务 18 | .start(); // 启动服务 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_6/ProviderTest_3.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_6; 2 | 3 | import org.laopopo.client.provider.DefaultProvider; 4 | import org.laopopo.common.exception.remoting.RemotingException; 5 | import org.laopopo.example.demo.service.HelloService_3; 6 | import org.laopopo.remoting.netty.NettyClientConfig; 7 | import org.laopopo.remoting.netty.NettyServerConfig; 8 | 9 | public class ProviderTest_3 { 10 | 11 | public static void main(String[] args) throws InterruptedException, RemotingException { 12 | 13 | DefaultProvider defaultProvider = new DefaultProvider(new NettyClientConfig(), new NettyServerConfig()); 14 | 15 | defaultProvider.registryAddress("127.0.0.1:18010") // 注册中心的地址 16 | .serviceListenPort(7001) // 暴露服务的端口 17 | .publishService(new HelloService_3()) // 暴露的服务 18 | .start(); // 启动服务 19 | 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/exception/rpc/RpcWrapperException.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.exception.rpc; 2 | 3 | 4 | /** 5 | * 6 | * @author BazingaLyn 7 | * @description 对服务进行编织的时候,发送的异常 8 | * @time 2016年9月9日 9 | * @modifytime 10 | */ 11 | public class RpcWrapperException extends RuntimeException { 12 | 13 | 14 | private static final long serialVersionUID = 5395455693773821359L; 15 | 16 | public RpcWrapperException() {} 17 | 18 | public RpcWrapperException(String message) { 19 | super(message); 20 | } 21 | 22 | public RpcWrapperException(String message, Throwable cause) { 23 | super(message, cause); 24 | } 25 | 26 | public RpcWrapperException(Throwable cause) { 27 | super(cause); 28 | } 29 | 30 | @Override 31 | public synchronized Throwable fillInStackTrace() { 32 | return this; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/provider/model/DefaultProviderInactiveProcessor.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.provider.model; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | 5 | import org.laopopo.client.provider.DefaultProvider; 6 | import org.laopopo.remoting.model.NettyChannelInactiveProcessor; 7 | 8 | /** 9 | * 10 | * @author BazingaLyn 11 | * @description provider的netty inactive触发的事件 12 | * @time 13 | * @modifytime 14 | */ 15 | public class DefaultProviderInactiveProcessor implements NettyChannelInactiveProcessor { 16 | 17 | private DefaultProvider defaultProvider; 18 | 19 | public DefaultProviderInactiveProcessor(DefaultProvider defaultProvider) { 20 | this.defaultProvider = defaultProvider; 21 | } 22 | 23 | @Override 24 | public void processChannelInactive(ChannelHandlerContext ctx) { 25 | defaultProvider.setProviderStateIsHealthy(false); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/transport/body/ProviderMetricsCustomBody.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.transport.body; 2 | 3 | import java.util.List; 4 | 5 | import org.laopopo.common.exception.remoting.RemotingCommmonCustomException; 6 | import org.laopopo.common.rpc.MetricsReporter; 7 | 8 | /** 9 | * 10 | * @author BazingaLyn 11 | * @description 管理员发送给监控中心的信息 12 | * @time 2016年9月1日 13 | * @modifytime 14 | */ 15 | public class ProviderMetricsCustomBody implements CommonCustomBody { 16 | 17 | 18 | private List metricsReporter; 19 | 20 | @Override 21 | public void checkFields() throws RemotingCommmonCustomException { 22 | } 23 | 24 | public List getMetricsReporter() { 25 | return metricsReporter; 26 | } 27 | 28 | public void setMetricsReporter(List metricsReporter) { 29 | this.metricsReporter = metricsReporter; 30 | } 31 | 32 | 33 | } 34 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/utils/Constants.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.utils; 2 | 3 | 4 | 5 | 6 | /** 7 | * 8 | * @author BazingaLyn 9 | * @description 一些常量 10 | * @time 2016年8月11日 11 | * @modifytime 12 | */ 13 | public class Constants { 14 | 15 | /**************可用的CPU数****************/ 16 | public static final int AVAILABLE_PROCESSORS = Runtime.getRuntime().availableProcessors(); 17 | /**********读心跳的默认时间间隔****************/ 18 | public static final int READER_IDLE_TIME_SECONDS = 60; 19 | /***********写心跳的默认时间间隔***********/ 20 | public static final int WRITER_IDLE_TIME_SECONDS = 30; 21 | /**********默认的权重负载***************/ 22 | public static final int DEFAULT_WEIGHT = 50; 23 | /******默认的consumer和provider之间默认的链接数*********/ 24 | public static final int DEFAULT_CONNECTION_COUNT = 1; 25 | /*****一分钟默认的最大调用次数******/ 26 | public static final int DEFAULT_MAX_CALLCOUN_TINMINUTE = 10000; 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/utils/Pair.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.utils; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description Key value Pojo 7 | * @time 8 | * @modifytime 9 | */ 10 | public class Pair { 11 | 12 | private K key; 13 | private V value; 14 | 15 | public Pair() {} 16 | 17 | public Pair(K key, V value) { 18 | this.key = key; 19 | this.value = value; 20 | } 21 | 22 | public K getKey() { 23 | return key; 24 | } 25 | 26 | public void setKey(K key) { 27 | this.key = key; 28 | } 29 | 30 | public V getValue() { 31 | return value; 32 | } 33 | 34 | public void setValue(V value) { 35 | this.value = value; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "Pair{" + 41 | "key=" + key + 42 | ", value=" + value + 43 | '}'; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/benchmark/BenchmarkRegistryTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.benchmark; 2 | 3 | import org.laopopo.base.registry.DefaultRegistryServer; 4 | import org.laopopo.base.registry.RegistryServerConfig; 5 | import org.laopopo.common.rpc.ServiceReviewState; 6 | import org.laopopo.remoting.netty.NettyServerConfig; 7 | 8 | /** 9 | * 10 | * @author BazingaLyn 11 | * @description 性能测试的注册中心端 12 | * @time 13 | * @modifytime 14 | */ 15 | public class BenchmarkRegistryTest { 16 | 17 | 18 | public static void main(String[] args) { 19 | 20 | NettyServerConfig config = new NettyServerConfig(); 21 | RegistryServerConfig registryServerConfig = new RegistryServerConfig(); 22 | registryServerConfig.setDefaultReviewState(ServiceReviewState.PASS_REVIEW); 23 | //注册中心的端口号 24 | config.setListenPort(18010); 25 | new DefaultRegistryServer(config,registryServerConfig).start(); 26 | 27 | } 28 | 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_1/ProviderTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_1; 2 | 3 | import org.laopopo.client.provider.DefaultProvider; 4 | import org.laopopo.common.exception.remoting.RemotingException; 5 | import org.laopopo.example.demo.service.ByeServiceImpl; 6 | import org.laopopo.example.demo.service.HelloSerivceImpl; 7 | import org.laopopo.remoting.netty.NettyClientConfig; 8 | import org.laopopo.remoting.netty.NettyServerConfig; 9 | 10 | public class ProviderTest { 11 | 12 | public static void main(String[] args) throws InterruptedException, RemotingException { 13 | 14 | DefaultProvider defaultProvider = new DefaultProvider(new NettyClientConfig(), new NettyServerConfig()); 15 | 16 | defaultProvider.registryAddress("127.0.0.1:18010") // 注册中心的地址 17 | .serviceListenPort(8899) // 暴露服务的端口 18 | .publishService(new HelloSerivceImpl(), new ByeServiceImpl()) // 暴露的服务 19 | .start(); // 启动服务 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /laopopo-monitor/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.bazinga 8 | laopopo 9 | 1.0.0 10 | 11 | laopopo-monitor 12 | laopopo-monitor 13 | http://maven.apache.org 14 | 15 | 16 | ${project.groupId} 17 | laopopo-common 18 | 19 | 20 | ${project.groupId} 21 | laopopo-remoting 22 | 23 | 24 | com.alibaba 25 | fastjson 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_2/ProviderTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_2; 2 | 3 | import org.laopopo.client.provider.DefaultProvider; 4 | import org.laopopo.common.exception.remoting.RemotingException; 5 | import org.laopopo.example.demo.service.ByeServiceImpl; 6 | import org.laopopo.example.demo.service.HelloSerivceImpl; 7 | import org.laopopo.remoting.netty.NettyClientConfig; 8 | import org.laopopo.remoting.netty.NettyServerConfig; 9 | 10 | public class ProviderTest { 11 | 12 | public static void main(String[] args) throws InterruptedException, RemotingException { 13 | 14 | DefaultProvider defaultProvider = new DefaultProvider(new NettyClientConfig(), new NettyServerConfig()); 15 | 16 | 17 | defaultProvider.registryAddress("127.0.0.1:18010") //注册中心的地址 18 | .serviceListenPort(8899) //暴露服务的地址 19 | .publishService(new HelloSerivceImpl(),new ByeServiceImpl()) //暴露的服务 20 | .start(); //启动服务 21 | 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_3/ProviderTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_3; 2 | 3 | import org.laopopo.client.provider.DefaultProvider; 4 | import org.laopopo.common.exception.remoting.RemotingException; 5 | import org.laopopo.example.demo.service.ByeServiceImpl; 6 | import org.laopopo.example.demo.service.HelloSerivceImpl; 7 | import org.laopopo.remoting.netty.NettyClientConfig; 8 | import org.laopopo.remoting.netty.NettyServerConfig; 9 | 10 | public class ProviderTest { 11 | 12 | public static void main(String[] args) throws InterruptedException, RemotingException { 13 | 14 | DefaultProvider defaultProvider = new DefaultProvider(new NettyClientConfig(), new NettyServerConfig()); 15 | 16 | defaultProvider.registryAddress("127.0.0.1:18010") // 注册中心的地址 17 | .monitorAddress("127.0.0.1:19010") // 监控中心的地址 18 | .serviceListenPort(8899) // 暴露服务的地址 19 | .publishService(new HelloSerivceImpl(), new ByeServiceImpl()) // 暴露的服务 20 | .start(); // 启动服务 21 | 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/benchmark/BenchmarkProviderTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.benchmark; 2 | 3 | import org.laopopo.client.provider.DefaultProvider; 4 | import org.laopopo.common.exception.remoting.RemotingException; 5 | import org.laopopo.example.demo.service.HelloServiceBenchmark; 6 | import org.laopopo.remoting.netty.NettyClientConfig; 7 | import org.laopopo.remoting.netty.NettyServerConfig; 8 | 9 | /** 10 | * 11 | * @author BazingaLyn 12 | * @description 性能测试的provider端 13 | * @time 14 | * @modifytime 15 | */ 16 | public class BenchmarkProviderTest { 17 | 18 | public static void main(String[] args) throws InterruptedException, RemotingException { 19 | 20 | DefaultProvider defaultProvider = new DefaultProvider(new NettyClientConfig(), new NettyServerConfig()); 21 | 22 | defaultProvider.registryAddress("127.0.0.1:18010") // 注册中心的地址 23 | .serviceListenPort(8899) // 暴露服务的地址 24 | .publishService(new HelloServiceBenchmark()) // 暴露的服务 25 | .start(); // 启动服务 26 | 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /laopopo-registry-default/src/main/java/org/laopopo/base/registry/model/ReviewRecord.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.base.registry.model; 2 | 3 | /** 4 | * 某个服务对应的审核记录 5 | * @author BazingaLyn 6 | * @description 7 | * @time 8 | * @modifytime 9 | */ 10 | public class ReviewRecord { 11 | 12 | private boolean isReviewPass; 13 | 14 | /** 15 | * 该服务是否降级 16 | */ 17 | private boolean isDegradeService; 18 | 19 | /** 20 | * 该服务的权重 21 | */ 22 | private int weightVal; 23 | 24 | public boolean isReviewPass() { 25 | return isReviewPass; 26 | } 27 | 28 | public void setReviewPass(boolean isReviewPass) { 29 | this.isReviewPass = isReviewPass; 30 | } 31 | 32 | public boolean isDegradeService() { 33 | return isDegradeService; 34 | } 35 | 36 | public void setDegradeService(boolean isDegradeService) { 37 | this.isDegradeService = isDegradeService; 38 | } 39 | 40 | public int getWeightVal() { 41 | return weightVal; 42 | } 43 | 44 | public void setWeightVal(int weightVal) { 45 | this.weightVal = weightVal; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /laopopo-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.bazinga 8 | laopopo 9 | 1.0.0 10 | 11 | laopopo-client 12 | laopopo-client 13 | http://maven.apache.org 14 | 15 | 16 | 17 | ${project.groupId} 18 | laopopo-common 19 | 20 | 21 | ${project.groupId} 22 | laopopo-remoting 23 | 24 | 25 | ch.qos.logback 26 | logback-classic 27 | 1.0.13 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /laopopo-registry-default/src/main/java/org/laopopo/base/registry/RegistryProviderServer.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.base.registry; 2 | 3 | import io.netty.channel.Channel; 4 | 5 | import org.laopopo.common.exception.remoting.RemotingSendRequestException; 6 | import org.laopopo.common.exception.remoting.RemotingTimeoutException; 7 | import org.laopopo.remoting.model.RemotingTransporter; 8 | 9 | /** 10 | * 11 | * @author BazingaLyn 12 | * @description 注册中心处理provider的服务接口 13 | * @time 2016年8月15日 14 | * @modifytime 15 | */ 16 | public interface RegistryProviderServer { 17 | 18 | 19 | /** 20 | * 处理provider发送过来的注册信息 21 | * @param remotingTransporter 里面的CommonCustomBody 是#PublishServiceCustomBody 22 | * @param channel 23 | * @return 24 | * @throws InterruptedException 25 | * @throws RemotingTimeoutException 26 | * @throws RemotingSendRequestException 27 | */ 28 | RemotingTransporter handlerRegister(RemotingTransporter remotingTransporter,Channel channel) throws RemotingSendRequestException, RemotingTimeoutException, InterruptedException; 29 | } 30 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_4/ConsumerTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_4; 2 | 3 | import org.laopopo.client.consumer.ConsumerClient; 4 | import org.laopopo.client.consumer.proxy.ProxyFactory; 5 | import org.laopopo.common.utils.UnresolvedAddress; 6 | 7 | /** 8 | * 9 | * @author BazingaLyn 10 | * @description 测试consumer直连provider,进行服务调用 11 | * @time 12 | * @modifytime 13 | */ 14 | public class ConsumerTest { 15 | 16 | public static void main(String[] args) throws Exception { 17 | 18 | ConsumerClient client = new ConsumerClient(); 19 | 20 | client.start(); 21 | 22 | UnresolvedAddress addresses = new UnresolvedAddress("127.0.0.1", 8899); 23 | 24 | HelloService helloService = ProxyFactory.factory(HelloService.class).consumer(client).addProviderAddress(addresses).timeoutMillis(3000l).newProxyInstance(); 25 | 26 | for(int i = 0; i < 10000;i++){ 27 | 28 | String str = helloService.sayHello("Lyncc"); 29 | System.out.println(str); 30 | } 31 | 32 | 33 | 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_5/ConsumerTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_5; 2 | 3 | import org.laopopo.client.consumer.ConsumerClient; 4 | import org.laopopo.client.consumer.proxy.ProxyFactory; 5 | import org.laopopo.common.utils.UnresolvedAddress; 6 | 7 | /** 8 | * 9 | * @author BazingaLyn 10 | * @description 测试 11 | * @time 12 | * @modifytime 13 | */ 14 | public class ConsumerTest { 15 | 16 | public static void main(String[] args) throws Exception { 17 | 18 | ConsumerClient client = new ConsumerClient(); 19 | 20 | client.start(); 21 | 22 | UnresolvedAddress addresses = new UnresolvedAddress("127.0.0.1", 8899); 23 | 24 | HelloService helloService = ProxyFactory.factory(HelloService.class).consumer(client).addProviderAddress(addresses).timeoutMillis(3000l).newProxyInstance(); 25 | 26 | for(int index = 1;index < 45;index++){ 27 | 28 | String str = helloService.sayHello("Lyncc"); 29 | System.out.println("当前调用的次数是:" + index); 30 | System.out.println(str); 31 | } 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/provider/ServiceProviderContainer.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.provider; 2 | 3 | import java.util.List; 4 | 5 | import org.laopopo.client.provider.DefaultServiceProviderContainer.CurrentServiceState; 6 | import org.laopopo.client.provider.model.ServiceWrapper; 7 | import org.laopopo.common.utils.Pair; 8 | 9 | /** 10 | * 11 | * @author BazingaLyn 12 | * @description 13 | * @time 14 | * @modifytime 2016年9月20日 15 | */ 16 | public interface ServiceProviderContainer { 17 | 18 | /** 19 | * 将服务放置在服务容器中,用来进行统一的管理 20 | * @param serviceName 该服务的名称 21 | * @param serviceWrapper 该服务的包装编织类 22 | */ 23 | void registerService(String serviceName, ServiceWrapper serviceWrapper); 24 | 25 | /** 26 | * 根据服务的名称来获取对应的服务编织类 27 | * @param serviceName 服务名 28 | * @return 服务编织类 29 | */ 30 | Pair lookupService(String serviceName); 31 | 32 | 33 | 34 | /** 35 | * 获取到所有需要自动降级的服务 36 | * @return 37 | */ 38 | List> getNeedAutoDegradeService(); 39 | 40 | 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/netty/idle/AcceptorIdleStateTrigger.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.netty.idle; 2 | 3 | import io.netty.channel.ChannelHandler; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.channel.ChannelInboundHandlerAdapter; 6 | import io.netty.handler.timeout.IdleState; 7 | import io.netty.handler.timeout.IdleStateEvent; 8 | 9 | import org.laopopo.common.exception.remoting.RemotingNoSighException; 10 | 11 | @ChannelHandler.Sharable 12 | public class AcceptorIdleStateTrigger extends ChannelInboundHandlerAdapter { 13 | 14 | @Override 15 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { 16 | System.out.println("accpet heartbeat"); 17 | if (evt instanceof IdleStateEvent) { 18 | IdleState state = ((IdleStateEvent) evt).state(); 19 | if (state == IdleState.READER_IDLE) { 20 | throw new RemotingNoSighException("no sign"); 21 | } 22 | } else { 23 | super.userEventTriggered(ctx, evt); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /laopopo-console/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] [%logger{0}] - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 65536 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /laopopo-client/src/test/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] [%logger{0}] - %msg%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 65536 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /laopopo-example/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] [%logger{0}] - %msg%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 65536 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/netty/idle/ConnectorIdleStateTrigger.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.netty.idle; 2 | 3 | import io.netty.channel.ChannelHandler; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.channel.ChannelInboundHandlerAdapter; 6 | import io.netty.handler.timeout.IdleState; 7 | import io.netty.handler.timeout.IdleStateEvent; 8 | 9 | import org.laopopo.remoting.model.Heartbeats; 10 | 11 | /** 12 | * 13 | * @author BazingaLyn 14 | * @description 15 | * @time 2016年8月12日13:44:19 16 | * @modifytime 17 | */ 18 | @ChannelHandler.Sharable 19 | public class ConnectorIdleStateTrigger extends ChannelInboundHandlerAdapter { 20 | 21 | @Override 22 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { 23 | if (evt instanceof IdleStateEvent) { 24 | IdleState state = ((IdleStateEvent) evt).state(); 25 | if (state == IdleState.WRITER_IDLE) { 26 | ctx.writeAndFlush(Heartbeats.heartbeatContent()); 27 | } 28 | } else { 29 | super.userEventTriggered(ctx, evt); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /laopopo-console/src/main/resources/spring-rpc.xml: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /laopopo-console/src/main/webapp/model.html: -------------------------------------------------------------------------------- 1 | 2 | 38 | 39 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/model/Heartbeats.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.model; 2 | 3 | import static org.laopopo.common.protocal.LaopopoProtocol.HEAD_LENGTH; 4 | 5 | import static org.laopopo.common.protocal.LaopopoProtocol.HEARTBEAT; 6 | import static org.laopopo.common.protocal.LaopopoProtocol.MAGIC; 7 | import io.netty.buffer.ByteBuf; 8 | import io.netty.buffer.Unpooled; 9 | 10 | /** 11 | * 12 | * @author BazingaLyn 13 | * @description 14 | * @time 15 | * @modifytime 16 | */ 17 | @SuppressWarnings("deprecation") 18 | public class Heartbeats { 19 | 20 | private static final ByteBuf HEARTBEAT_BUF; 21 | 22 | static { 23 | ByteBuf buf = Unpooled.buffer(HEAD_LENGTH); 24 | buf.writeShort(MAGIC); 25 | buf.writeByte(HEARTBEAT); 26 | buf.writeByte(0); 27 | buf.writeLong(0); 28 | buf.writeInt(0); 29 | HEARTBEAT_BUF = Unpooled.unmodifiableBuffer(Unpooled.unreleasableBuffer(buf)); 30 | } 31 | 32 | /** 33 | * Returns the shared heartbeat content. 34 | */ 35 | public static ByteBuf heartbeatContent() { 36 | return HEARTBEAT_BUF.duplicate(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /laopopo-spring-support/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.bazinga 7 | laopopo 8 | 1.0.0 9 | 10 | laopopo-spring-support 11 | laopopo-spring-support 12 | http://maven.apache.org 13 | 14 | 15 | 16 | ${project.groupId} 17 | laopopo-remoting 18 | 19 | 20 | ${project.groupId} 21 | laopopo-client 22 | 23 | 24 | org.springframework 25 | spring-context 26 | provided 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/utils/ChannelGroup.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.utils; 2 | 3 | import io.netty.channel.Channel; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * @description 服务消费者实例和服务提供者实例之间的Netty channel组 9 | * 因为一个服务消费者的实例和一个服务提供者之间的连接可以有多个 10 | * @time 2016年8月14日 11 | * @modifytime 12 | */ 13 | public interface ChannelGroup { 14 | 15 | /** 16 | * 轮询获取某个服务消费者和服务提供者之间的某个channel 17 | * @return 18 | */ 19 | Channel next(); 20 | 21 | /** 22 | * 向group组中增加一个active的channel 23 | * @param channel 24 | * @return 25 | */ 26 | boolean add(Channel channel); 27 | 28 | /** 29 | * 将group组中的某个channel移除掉 30 | * @param channel 31 | * @return 32 | */ 33 | boolean remove(Channel channel); 34 | 35 | /** 36 | * 设置整个group的权重 37 | * @param weight 38 | */ 39 | void setWeight(int weight); 40 | 41 | /** 42 | * 获取到整个channelGroup的权重 43 | * @return 44 | */ 45 | int getWeight(); 46 | 47 | /** 48 | * 49 | * @return 50 | */ 51 | int size(); 52 | 53 | /** 54 | * 55 | * @return 56 | */ 57 | boolean isAvailable(); 58 | 59 | /** 60 | * 61 | * @return 62 | */ 63 | UnresolvedAddress getAddress(); 64 | 65 | } 66 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/consumer/ConsumerConfig.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.consumer; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 消费端配置属性 7 | * @time 8 | * @modifytime 9 | */ 10 | public class ConsumerConfig { 11 | 12 | private int retryConnectionRegistryTimes = 4; 13 | 14 | private long maxRetryConnectionRegsitryTime = 5000; 15 | 16 | private long registryTimeout = 3000; 17 | 18 | public int getRetryConnectionRegistryTimes() { 19 | return retryConnectionRegistryTimes; 20 | } 21 | 22 | public void setRetryConnectionRegistryTimes(int retryConnectionRegistryTimes) { 23 | this.retryConnectionRegistryTimes = retryConnectionRegistryTimes; 24 | } 25 | 26 | public long getMaxRetryConnectionRegsitryTime() { 27 | return maxRetryConnectionRegsitryTime; 28 | } 29 | 30 | public void setMaxRetryConnectionRegsitryTime(long maxRetryConnectionRegsitryTime) { 31 | this.maxRetryConnectionRegsitryTime = maxRetryConnectionRegsitryTime; 32 | } 33 | 34 | public long getRegistryTimeout() { 35 | return registryTimeout; 36 | } 37 | 38 | public void setRegistryTimeout(long registryTimeout) { 39 | this.registryTimeout = registryTimeout; 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/exception/rpc/RemoteException.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.exception.rpc; 2 | 3 | import java.net.SocketAddress; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * @description 9 | * @time 10 | * @modifytime 11 | */ 12 | public class RemoteException extends RuntimeException { 13 | 14 | private static final long serialVersionUID = -6516335527982400712L; 15 | 16 | private final SocketAddress remoteAddress; 17 | 18 | public RemoteException(SocketAddress remoteAddress) { 19 | this.remoteAddress = remoteAddress; 20 | } 21 | 22 | public RemoteException(Throwable cause, SocketAddress remoteAddress) { 23 | super(cause); 24 | this.remoteAddress = remoteAddress; 25 | } 26 | 27 | public RemoteException(String message, SocketAddress remoteAddress) { 28 | super(message); 29 | this.remoteAddress = remoteAddress; 30 | } 31 | 32 | public RemoteException(String message, Throwable cause, SocketAddress remoteAddress) { 33 | super(message, cause); 34 | this.remoteAddress = remoteAddress; 35 | } 36 | 37 | public SocketAddress getRemoteAddress() { 38 | return remoteAddress; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/utils/UnresolvedAddress.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.utils; 2 | 3 | 4 | /** 5 | * 6 | * @author BazingaLyn 7 | * @description 8 | * @time 9 | * @modifytime 10 | */ 11 | public class UnresolvedAddress { 12 | 13 | private final String host; 14 | private final int port; 15 | 16 | public UnresolvedAddress(String host, int port) { 17 | this.host = host; 18 | this.port = port; 19 | } 20 | 21 | public String getHost() { 22 | return host; 23 | } 24 | 25 | public int getPort() { 26 | return port; 27 | } 28 | 29 | @Override 30 | public boolean equals(Object o) { 31 | if (this == o) return true; 32 | if (o == null || getClass() != o.getClass()) return false; 33 | 34 | UnresolvedAddress that = (UnresolvedAddress) o; 35 | 36 | return port == that.port && host.equals(that.host); 37 | } 38 | 39 | @Override 40 | public int hashCode() { 41 | int result = host.hashCode(); 42 | result = 31 * result + port; 43 | return result; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return host + ':' + port; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/netty/NettyClientTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.netty; 2 | 3 | import org.laopopo.common.exception.remoting.RemotingException; 4 | import org.laopopo.example.netty.TestCommonCustomBody.ComplexTestObj; 5 | import org.laopopo.remoting.model.RemotingTransporter; 6 | import org.laopopo.remoting.netty.NettyClientConfig; 7 | import org.laopopo.remoting.netty.NettyRemotingClient; 8 | 9 | public class NettyClientTest { 10 | 11 | public static final byte TEST = -1; 12 | 13 | public static void main(String[] args) throws InterruptedException, RemotingException { 14 | NettyClientConfig nettyClientConfig = new NettyClientConfig(); 15 | NettyRemotingClient client = new NettyRemotingClient(nettyClientConfig); 16 | client.start(); 17 | 18 | ComplexTestObj complexTestObj = new ComplexTestObj("attr1", 2); 19 | TestCommonCustomBody commonCustomHeader = new TestCommonCustomBody(1, "test",complexTestObj); 20 | 21 | RemotingTransporter remotingTransporter = RemotingTransporter.createRequestTransporter(TEST, commonCustomHeader); 22 | RemotingTransporter request = client.invokeSync("127.0.0.1:18001", remotingTransporter, 3000); 23 | System.out.println(request); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/transport/body/AckCustomBody.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.transport.body; 2 | 3 | import org.laopopo.common.exception.remoting.RemotingCommmonCustomException; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * @description ack信息 9 | * @time 2016年8月16日 10 | * @modifytime 2016年8月17日 11 | */ 12 | public class AckCustomBody implements CommonCustomBody { 13 | 14 | //request请求id 15 | private long requestId; 16 | 17 | //是否消费处理成功 18 | private boolean success; 19 | 20 | 21 | public AckCustomBody(long requestId, boolean success) { 22 | this.requestId = requestId; 23 | this.success = success; 24 | } 25 | 26 | @Override 27 | public void checkFields() throws RemotingCommmonCustomException { 28 | } 29 | 30 | public long getRequestId() { 31 | return requestId; 32 | } 33 | 34 | public void setRequestId(long requestId) { 35 | this.requestId = requestId; 36 | } 37 | 38 | public boolean isSuccess() { 39 | return success; 40 | } 41 | 42 | public void setSuccess(boolean success) { 43 | this.success = success; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return "AckCustomBody [requestId=" + requestId + ", success=" + success + "]"; 49 | } 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/annotation/RPCService.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.annotation; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * 11 | * @author BazingaLyn 12 | * @description 服务提供端提供服务的Annotation 13 | * @time 2016年8月19日 14 | * @modifytime 15 | */ 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Target({ ElementType.METHOD }) 18 | @Documented 19 | public @interface RPCService { 20 | 21 | 22 | public String serviceName() default ""; //服务名 23 | public int weight() default 50; //负载访问权重 24 | public String responsibilityName() default "system"; //负责人名 25 | public int connCount() default 1; //单实例连接数,注册中心该参数有效,直连无效 26 | public boolean isVIPService() default false; //是否是VIP服务 27 | public boolean isSupportDegradeService() default false; //是否支持降级 28 | public String degradeServicePath() default ""; //如果支持降级,降级服务的路径 29 | public String degradeServiceDesc() default ""; //降级服务的描述 30 | public boolean isFlowController() default true; //是否单位时间限流 31 | public long maxCallCountInMinute() default 100000; //单位时间的最大调用量 32 | 33 | } 34 | -------------------------------------------------------------------------------- /laopopo-monitor/src/main/java/org/laopopo/monitor/MonitorConfig.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.monitor; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * @description monitor端的一些参数配置 9 | * @time 2016年9月7日 10 | * @modifytime 11 | */ 12 | public class MonitorConfig { 13 | 14 | //持久化保存的位置 15 | private String storePathRootDir = System.getProperty("user.home") + File.separator + "test" + File.separator + "historyMetrics.json"; 16 | 17 | //每个多久时间刷盘到硬盘上,默认30s 18 | private int persistTime = 30; 19 | 20 | //当手动修改历史记录的时候,历史记录发生改变的时候,是否立即进行持久化操作 21 | private boolean changedPersistRightnow = false; 22 | 23 | public String getStorePathRootDir() { 24 | return storePathRootDir; 25 | } 26 | 27 | public void setStorePathRootDir(String storePathRootDir) { 28 | this.storePathRootDir = storePathRootDir; 29 | } 30 | 31 | public int getPersistTime() { 32 | return persistTime; 33 | } 34 | 35 | public void setPersistTime(int persistTime) { 36 | this.persistTime = persistTime; 37 | } 38 | 39 | public boolean isChangedPersistRightnow() { 40 | return changedPersistRightnow; 41 | } 42 | 43 | public void setChangedPersistRightnow(boolean changedPersistRightnow) { 44 | this.changedPersistRightnow = changedPersistRightnow; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /laopopo-remoting/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.bazinga 7 | laopopo 8 | 1.0.0 9 | 10 | laopopo-remoting 11 | laopopo-remoting 12 | http://maven.apache.org 13 | 14 | 15 | 16 | 17 | 18 | ${project.groupId} 19 | laopopo-common 20 | 21 | 22 | 23 | io.netty 24 | netty-all 25 | 26 | 27 | org.slf4j 28 | slf4j-api 29 | 30 | 31 | net.bytebuddy 32 | byte-buddy 33 | 34 | 35 | 36 | org.xerial.snappy 37 | snappy-java 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /laopopo-registry-default/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.bazinga 8 | laopopo 9 | 1.0.0 10 | 11 | laopopo-registry-default 12 | laopopo-registry-default 13 | http://maven.apache.org 14 | 15 | 16 | 17 | ${project.groupId} 18 | laopopo-registry 19 | 20 | 21 | ${project.groupId} 22 | laopopo-remoting 23 | 24 | 25 | com.alibaba 26 | fastjson 27 | 28 | 29 | org.slf4j 30 | slf4j-api 31 | 32 | 33 | ch.qos.logback 34 | logback-classic 35 | 1.0.13 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /laopopo-console/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | laopopo-RPC-monitor 7 | 8 | 9 | logbackConfigLocation 10 | classpath:logback.xml 11 | 12 | 13 | ch.qos.logback.ext.spring.web.LogbackConfigListener 14 | 15 | 16 | 17 | springmvc 18 | org.springframework.web.servlet.DispatcherServlet 19 | 20 | contextConfigLocation 21 | classpath*:spring-servlet.xml 22 | 23 | 1 24 | 25 | 26 | springmvc 27 | *.do 28 | 29 | 30 | 31 | /WEB-INF/index.html 32 | /index.html 33 | 34 | 35 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_7/ConsumerTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_7; 2 | 3 | import org.laopopo.client.consumer.ConsumerClient; 4 | import org.laopopo.client.consumer.proxy.ProxyFactory; 5 | import org.laopopo.common.loadbalance.LoadBalanceStrategy; 6 | import org.laopopo.common.utils.UnresolvedAddress; 7 | import org.laopopo.example.generic.test_5.HelloService; 8 | 9 | public class ConsumerTest { 10 | 11 | public static void main(String[] args) throws Exception { 12 | 13 | ConsumerClient client = new ConsumerClient(); 14 | 15 | client.start(); 16 | 17 | UnresolvedAddress addresses_1 = new UnresolvedAddress("127.0.0.1", 9001); 18 | UnresolvedAddress addresses_2 = new UnresolvedAddress("127.0.0.1", 8001); 19 | UnresolvedAddress addresses_3 = new UnresolvedAddress("127.0.0.1", 7001); 20 | 21 | HelloService helloService = ProxyFactory.factory(HelloService.class).consumer(client).addProviderAddress(addresses_1,addresses_2,addresses_3).loadBalance(LoadBalanceStrategy.WEIGHTINGRANDOM).timeoutMillis(3000l).newProxyInstance(); 22 | 23 | for(int index = 1;index < 45;index++){ 24 | 25 | Thread.sleep(1000l); 26 | String str = helloService.sayHello("Lyncc"); 27 | System.out.println("当前调用的次数是:" + index); 28 | System.out.println(str); 29 | } 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_2/ConsumerTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_2; 2 | 3 | import org.laopopo.client.consumer.ConsumerClient; 4 | import org.laopopo.client.consumer.ConsumerConfig; 5 | import org.laopopo.client.consumer.Consumer.SubscribeManager; 6 | import org.laopopo.client.consumer.proxy.ProxyFactory; 7 | import org.laopopo.remoting.netty.NettyClientConfig; 8 | 9 | public class ConsumerTest { 10 | 11 | public static void main(String[] args) throws Exception { 12 | 13 | NettyClientConfig registryNettyClientConfig = new NettyClientConfig(); 14 | registryNettyClientConfig.setDefaultAddress("127.0.0.1:18010"); 15 | 16 | NettyClientConfig provideClientConfig = new NettyClientConfig(); 17 | 18 | ConsumerClient client = new ConsumerClient(registryNettyClientConfig, provideClientConfig, new ConsumerConfig()); 19 | 20 | client.start(); 21 | 22 | SubscribeManager subscribeManager = client.subscribeService("LAOPOPO.TEST.SAYHELLO"); 23 | 24 | if (!subscribeManager.waitForAvailable(3000l)) { 25 | throw new Exception("no service provider"); 26 | } 27 | 28 | HelloService helloService = ProxyFactory.factory(HelloService.class).consumer(client).timeoutMillis(3000l).newProxyInstance(); 29 | 30 | String str = helloService.sayHello("Lyncc"); 31 | 32 | System.out.println(str); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /laopopo-example/src/main/resources/spring-provider.xml: -------------------------------------------------------------------------------- 1 | 2 | 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 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/other/StackCopyTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.other; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 8 | * @author BazingaLyn 9 | * @description 堆copy的测试 10 | * @time 11 | * @modifytime 12 | */ 13 | public class StackCopyTest { 14 | 15 | private static List ls = new ArrayList(); 16 | 17 | 18 | public static void main(String[] args) throws InterruptedException { 19 | 20 | 21 | Thread thread = new Thread(new Runnable() { 22 | 23 | @Override 24 | public void run() { 25 | 26 | for(int i = 0;i<50000;i++){ 27 | try { 28 | Thread.sleep(20l); 29 | } catch (InterruptedException e) { 30 | e.printStackTrace(); 31 | } 32 | ls.add(i+"hehe"); 33 | ls.add("hehe"); 34 | ls.add("hehe"); 35 | ls.add("hehe"); 36 | 37 | } 38 | } 39 | }); 40 | thread.start(); 41 | 42 | for(int j = 0;j<30;j++){ 43 | callXXmethod(); 44 | } 45 | } 46 | 47 | 48 | private static void callXXmethod() throws InterruptedException { 49 | List _ls = ls; 50 | System.out.println("最初的复制的一份的size "+_ls.size()); 51 | 52 | Thread.sleep(5000l); 53 | _ls.remove(1); 54 | System.out.println("停顿5秒复制的一份的size "+_ls.size()); 55 | System.out.println("全局变量的一份的size "+ls.size()); 56 | System.out.println("==========================="); 57 | 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/netty/NettyServerTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.netty; 2 | 3 | import static org.laopopo.common.serialization.SerializerHolder.serializerImpl; 4 | import io.netty.channel.ChannelHandlerContext; 5 | 6 | import java.util.concurrent.Executors; 7 | 8 | import org.laopopo.common.protocal.LaopopoProtocol; 9 | import org.laopopo.remoting.model.NettyRequestProcessor; 10 | import org.laopopo.remoting.model.RemotingTransporter; 11 | import org.laopopo.remoting.netty.NettyRemotingServer; 12 | import org.laopopo.remoting.netty.NettyServerConfig; 13 | 14 | public class NettyServerTest { 15 | 16 | public static final byte TEST = -1; 17 | 18 | public static void main(String[] args) { 19 | 20 | NettyServerConfig config = new NettyServerConfig(); 21 | config.setListenPort(18001); 22 | NettyRemotingServer server = new NettyRemotingServer(config); 23 | server.registerProecessor(TEST, new NettyRequestProcessor() { 24 | 25 | @Override 26 | public RemotingTransporter processRequest(ChannelHandlerContext ctx, RemotingTransporter transporter) throws Exception { 27 | transporter.setCustomHeader(serializerImpl().readObject(transporter.bytes(), TestCommonCustomBody.class)); 28 | System.out.println(transporter); 29 | transporter.setTransporterType(LaopopoProtocol.RESPONSE_REMOTING); 30 | return transporter; 31 | } 32 | }, Executors.newCachedThreadPool()); 33 | server.start(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /laopopo-example/src/main/resources/spring-consumer.xml: -------------------------------------------------------------------------------- 1 | 2 | 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 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_6/ConsumerTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_6; 2 | 3 | import org.laopopo.client.consumer.ConsumerClient; 4 | import org.laopopo.client.consumer.ConsumerConfig; 5 | import org.laopopo.client.consumer.Consumer.SubscribeManager; 6 | import org.laopopo.client.consumer.proxy.ProxyFactory; 7 | import org.laopopo.remoting.netty.NettyClientConfig; 8 | 9 | public class ConsumerTest { 10 | 11 | public static void main(String[] args) throws Exception { 12 | 13 | NettyClientConfig registryNettyClientConfig = new NettyClientConfig(); 14 | registryNettyClientConfig.setDefaultAddress("127.0.0.1:18010"); 15 | 16 | NettyClientConfig provideClientConfig = new NettyClientConfig(); 17 | 18 | ConsumerClient client = new ConsumerClient(registryNettyClientConfig, provideClientConfig, new ConsumerConfig()); 19 | 20 | client.start(); 21 | 22 | SubscribeManager subscribeManager = client.subscribeService("LAOPOPO.TEST.SAYHELLO"); 23 | 24 | if (!subscribeManager.waitForAvailable(3000l)) { 25 | throw new Exception("no service provider"); 26 | } 27 | 28 | HelloService helloService = ProxyFactory.factory(HelloService.class).consumer(client).timeoutMillis(3000l).newProxyInstance(); 29 | 30 | for(int index = 0;index < 10000;index++){ 31 | 32 | String str = helloService.sayHello("Lyncc"); 33 | 34 | System.out.println(str); 35 | 36 | Thread.sleep(1000l); 37 | } 38 | 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /laopopo-console/src/main/resources/spring-servlet.xml: -------------------------------------------------------------------------------- 1 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_3/ConsumerTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_3; 2 | 3 | import org.laopopo.client.consumer.ConsumerClient; 4 | import org.laopopo.client.consumer.ConsumerConfig; 5 | import org.laopopo.client.consumer.Consumer.SubscribeManager; 6 | import org.laopopo.client.consumer.proxy.ProxyFactory; 7 | import org.laopopo.common.exception.rpc.NoServiceException; 8 | import org.laopopo.remoting.netty.NettyClientConfig; 9 | 10 | public class ConsumerTest { 11 | 12 | public static void main(String[] args) throws Exception { 13 | 14 | NettyClientConfig registryNettyClientConfig = new NettyClientConfig(); 15 | registryNettyClientConfig.setDefaultAddress("127.0.0.1:18010"); 16 | 17 | NettyClientConfig provideClientConfig = new NettyClientConfig(); 18 | 19 | ConsumerClient client = new ConsumerClient(registryNettyClientConfig, provideClientConfig, new ConsumerConfig()); 20 | 21 | client.start(); 22 | 23 | SubscribeManager subscribeManager = client.subscribeService("LAOPOPO.TEST.SAYHELLO"); 24 | 25 | if (!subscribeManager.waitForAvailable(3000l)) { 26 | throw new NoServiceException("no service provider"); 27 | } 28 | 29 | HelloService helloService = ProxyFactory.factory(HelloService.class).consumer(client).timeoutMillis(3000l).newProxyInstance(); 30 | 31 | for(int index = 0;index < 100000;index++){ 32 | 33 | String str = helloService.sayHello("Lyncc"); 34 | 35 | System.out.println(str); 36 | 37 | Thread.sleep(500l); 38 | } 39 | 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/transport/body/SubcribeResultCustomBody.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.transport.body; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.laopopo.common.exception.remoting.RemotingCommmonCustomException; 7 | import org.laopopo.common.loadbalance.LoadBalanceStrategy; 8 | import org.laopopo.common.rpc.RegisterMeta; 9 | 10 | /** 11 | * 12 | * @author BazingaLyn 13 | * @description 注册中心向consumer反馈的服务信息 14 | * @time 2016年8月15日 15 | * @modifytime 2016年8月18日 修改成List 这样方便订阅的时候,一起将所有的服务信息发送出去 16 | */ 17 | public class SubcribeResultCustomBody implements CommonCustomBody { 18 | 19 | private String serviceName; 20 | 21 | private LoadBalanceStrategy loadBalanceStrategy; 22 | 23 | private List registerMeta = new ArrayList(); 24 | 25 | @Override 26 | public void checkFields() throws RemotingCommmonCustomException { 27 | } 28 | 29 | public List getRegisterMeta() { 30 | return registerMeta; 31 | } 32 | 33 | public void setRegisterMeta(List registerMeta) { 34 | this.registerMeta = registerMeta; 35 | } 36 | 37 | public LoadBalanceStrategy getLoadBalanceStrategy() { 38 | return loadBalanceStrategy; 39 | } 40 | 41 | public void setLoadBalanceStrategy(LoadBalanceStrategy loadBalanceStrategy) { 42 | this.loadBalanceStrategy = loadBalanceStrategy; 43 | } 44 | 45 | public String getServiceName() { 46 | return serviceName; 47 | } 48 | 49 | public void setServiceName(String serviceName) { 50 | this.serviceName = serviceName; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/transport/body/RequestCustomBody.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.transport.body; 2 | 3 | import java.util.concurrent.atomic.AtomicLong; 4 | 5 | import org.laopopo.common.exception.remoting.RemotingCommmonCustomException; 6 | 7 | /** 8 | * 9 | * @author BazingaLyn 10 | * @description 远程调用的参数 11 | * @time 2016年8月19日 12 | * @modifytime 13 | */ 14 | public class RequestCustomBody implements CommonCustomBody { 15 | 16 | private static final AtomicLong invokeIdGenerator = new AtomicLong(0); 17 | 18 | private final long invokeId; //调用的Id,全局只有一个 19 | private String serviceName; //调用的服务名 20 | private Object[] args; //调用服务的参数 21 | private long timestamp; //调用的时间 22 | 23 | public RequestCustomBody() { 24 | this(invokeIdGenerator.getAndIncrement()); 25 | } 26 | 27 | public RequestCustomBody(long invokeId) { 28 | this.invokeId = invokeId; 29 | } 30 | 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 Object[] getArgs() { 42 | return args; 43 | } 44 | 45 | public void setArgs(Object[] args) { 46 | this.args = args; 47 | } 48 | 49 | public long getTimestamp() { 50 | return timestamp; 51 | } 52 | 53 | public void setTimestamp(long timestamp) { 54 | this.timestamp = timestamp; 55 | } 56 | 57 | public long getInvokeId() { 58 | return invokeId; 59 | } 60 | 61 | @Override 62 | public void checkFields() throws RemotingCommmonCustomException { 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/netty/RemotingServer.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.netty; 2 | 3 | import io.netty.channel.Channel; 4 | 5 | import java.util.concurrent.ExecutorService; 6 | 7 | import org.laopopo.common.exception.remoting.RemotingSendRequestException; 8 | import org.laopopo.common.exception.remoting.RemotingTimeoutException; 9 | import org.laopopo.common.utils.Pair; 10 | import org.laopopo.remoting.model.NettyChannelInactiveProcessor; 11 | import org.laopopo.remoting.model.NettyRequestProcessor; 12 | import org.laopopo.remoting.model.RemotingTransporter; 13 | 14 | /** 15 | * 16 | * @author BazingaLyn 17 | * @description netty服务端的一些抽象方法 18 | * 1)作为服务端自然要处理来自客户端请求的一些请求,每一个请求都会有一个与之对应的处理器 19 | * 2)这样做的好处就是简化了netty的handler的配置,将handler中的业务逻辑放置到每一个对应的处理器中来 20 | * @time 2016年8月10日14:48:00 21 | * @modifytime 22 | */ 23 | public interface RemotingServer extends BaseRemotingService { 24 | 25 | void registerProecessor(final byte requestCode, final NettyRequestProcessor processor,final ExecutorService executor); 26 | 27 | void registerChannelInactiveProcessor(final NettyChannelInactiveProcessor processor,final ExecutorService executor); 28 | 29 | void registerDefaultProcessor(final NettyRequestProcessor processor, final ExecutorService executor); 30 | 31 | Pair getProcessorPair(final int requestCode); 32 | 33 | RemotingTransporter invokeSync(final Channel channel, final RemotingTransporter request, final long timeoutMillis) throws InterruptedException, RemotingSendRequestException, 34 | RemotingTimeoutException; 35 | } 36 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/serializer/SerializerTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.serializer; 2 | 3 | import org.laopopo.example.netty.TestCommonCustomBody; 4 | import org.laopopo.example.netty.TestCommonCustomBody.ComplexTestObj; 5 | import static org.laopopo.common.serialization.SerializerHolder.serializerImpl; 6 | 7 | /** 8 | * 9 | * @author BazingaLyn 10 | * @description 11 | * 12 | * 1)使用protoStuff序列化测试 13 | * 修改org.laopopo.common.serialization.Serializer中的内容为: 14 | * org.laopopo.common.serialization.proto.ProtoStuffSerializer 15 | * 16 | * 2)使用fastjson序列化测试 17 | * 修改org.laopopo.common.serialization.Serializer中的内容为: 18 | * org.laopopo.common.serialization.fastjson.FastjsonSerializer 19 | * 20 | * 3)使用kryo序列化测试 21 | * 修改org.laopopo.common.serialization.Serializer中的内容为: 22 | * org.laopopo.common.serialization.kryo.KryoSerializer 23 | * 24 | * @time 2016年8月12日 25 | * @modifytime 26 | */ 27 | public class SerializerTest { 28 | 29 | public static void main(String[] args) { 30 | 31 | long beginTime = System.currentTimeMillis(); 32 | 33 | for(int i = 0;i < 100000;i++){ 34 | ComplexTestObj complexTestObj = new ComplexTestObj("attr1", 2); 35 | TestCommonCustomBody commonCustomHeader = new TestCommonCustomBody(1, "test",complexTestObj); 36 | byte[] bytes = serializerImpl().writeObject(commonCustomHeader); 37 | 38 | TestCommonCustomBody body = serializerImpl().readObject(bytes, TestCommonCustomBody.class); 39 | } 40 | 41 | long endTime = System.currentTimeMillis(); 42 | 43 | System.out.println((endTime - beginTime)); 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/provider/DefaultProviderRPCProcessor.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.provider; 2 | 3 | import static org.laopopo.common.protocal.LaopopoProtocol.RPC_REQUEST; 4 | import io.netty.channel.ChannelHandlerContext; 5 | 6 | import org.laopopo.remoting.ConnectionUtils; 7 | import org.laopopo.remoting.model.NettyRequestProcessor; 8 | import org.laopopo.remoting.model.RemotingTransporter; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | /** 13 | * 14 | * @author BazingaLyn 15 | * @description provider端 16 | * @time 17 | * @modifytime 18 | */ 19 | public class DefaultProviderRPCProcessor implements NettyRequestProcessor { 20 | 21 | private static final Logger logger = LoggerFactory.getLogger(DefaultProviderRPCProcessor.class); 22 | 23 | private DefaultProvider defaultProvider; 24 | 25 | public DefaultProviderRPCProcessor(DefaultProvider defaultProvider) { 26 | this.defaultProvider = defaultProvider; 27 | } 28 | 29 | @Override 30 | public RemotingTransporter processRequest(ChannelHandlerContext ctx, RemotingTransporter request) throws Exception { 31 | 32 | if (logger.isDebugEnabled()) { 33 | logger.debug("receive request, {} {} {}",// 34 | request.getCode(), // 35 | ConnectionUtils.parseChannelRemoteAddr(ctx.channel()), // 36 | request); 37 | } 38 | 39 | switch (request.getCode()) { 40 | case RPC_REQUEST: 41 | //这边稍微特殊处理一下,可以返回null,我们不需要叫外层代码帮我们writeAndFlush 发出请求,因为我们持有channel,这样做rpc可以更加灵活一点 42 | this.defaultProvider.handlerRPCRequest(request,ctx.channel()); 43 | break; 44 | } 45 | return null; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/metrics/Meter.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.metrics; 2 | 3 | import java.util.concurrent.atomic.AtomicLong; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * @description RPC调用统计 9 | * @time 2016年9月18日 10 | * @modifytime 11 | */ 12 | public class Meter { 13 | 14 | private String serviceName; //服务名 15 | private AtomicLong callCount = new AtomicLong(0l); //调用次数 16 | private AtomicLong failedCount = new AtomicLong(0l); //失败次数 17 | private AtomicLong totalCallTime = new AtomicLong(0l); //总的调用时间 18 | private AtomicLong totalRequestSize = new AtomicLong(0l);//入参大小 19 | 20 | public Meter(String serviceName) { 21 | this.serviceName = serviceName; 22 | } 23 | 24 | public String getServiceName() { 25 | return serviceName; 26 | } 27 | 28 | public void setServiceName(String serviceName) { 29 | this.serviceName = serviceName; 30 | } 31 | 32 | public AtomicLong getCallCount() { 33 | return callCount; 34 | } 35 | 36 | public void setCallCount(AtomicLong callCount) { 37 | this.callCount = callCount; 38 | } 39 | 40 | public AtomicLong getFailedCount() { 41 | return failedCount; 42 | } 43 | 44 | public void setFailedCount(AtomicLong failedCount) { 45 | this.failedCount = failedCount; 46 | } 47 | 48 | public AtomicLong getTotalCallTime() { 49 | return totalCallTime; 50 | } 51 | 52 | public void setTotalCallTime(AtomicLong totalCallTime) { 53 | this.totalCallTime = totalCallTime; 54 | } 55 | 56 | public AtomicLong getTotalRequestSize() { 57 | return totalRequestSize; 58 | } 59 | 60 | public void setTotalRequestSize(AtomicLong totalRequestSize) { 61 | this.totalRequestSize = totalRequestSize; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /laopopo-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.bazinga 8 | laopopo 9 | 1.0.0 10 | 11 | laopopo-common 12 | laopopo-common 13 | http://maven.apache.org 14 | 15 | 16 | 17 | io.protostuff 18 | protostuff-core 19 | 20 | 21 | io.protostuff 22 | protostuff-runtime 23 | 24 | 25 | org.objenesis 26 | objenesis 27 | 28 | 29 | io.netty 30 | netty-all 31 | 32 | 33 | org.slf4j 34 | slf4j-api 35 | 36 | 37 | cglib 38 | cglib 39 | 40 | 41 | net.bytebuddy 42 | byte-buddy 43 | 44 | 45 | com.alibaba 46 | fastjson 47 | 48 | 49 | com.esotericsoftware.kryo 50 | kryo 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/serialization/kryo/KryoSerializer.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.serialization.kryo; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.IOException; 6 | 7 | import org.laopopo.common.serialization.Serializer; 8 | 9 | import com.esotericsoftware.kryo.Kryo; 10 | import com.esotericsoftware.kryo.io.Input; 11 | import com.esotericsoftware.kryo.io.Output; 12 | import com.esotericsoftware.kryo.serializers.JavaSerializer; 13 | 14 | /** 15 | * 16 | * @author BazingaLyn 17 | * @description 使用Kryo序列化 18 | * 需要实现java.io.Serializable接口 19 | * @time 2016年8月12日 20 | * @modifytime 21 | */ 22 | public class KryoSerializer implements Serializer { 23 | 24 | @Override 25 | public byte[] writeObject(T obj) { 26 | Kryo kryo = new Kryo(); 27 | kryo.setReferences(false); 28 | kryo.register(obj.getClass(), new JavaSerializer()); 29 | 30 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 31 | Output output = new Output(baos); 32 | kryo.writeClassAndObject(output, obj); 33 | output.flush(); 34 | output.close(); 35 | 36 | byte[] b = baos.toByteArray(); 37 | try { 38 | baos.flush(); 39 | baos.close(); 40 | } catch (IOException e) { 41 | e.printStackTrace(); 42 | } 43 | return b; 44 | } 45 | 46 | @SuppressWarnings("unchecked") 47 | @Override 48 | public T readObject(byte[] bytes, Class clazz) { 49 | Kryo kryo = new Kryo(); 50 | kryo.setReferences(false); 51 | kryo.register(clazz, new JavaSerializer()); 52 | 53 | ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 54 | Input input = new Input(bais); 55 | return (T) kryo.readClassAndObject(input); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /laopopo-console/src/main/java/org/laopopo/console/model/ManagerRPC.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.console.model; 2 | 3 | /** 4 | * 5 | * @author BazingaLyn 6 | * @description 管理员在管理页面发出来的请求命令 TODO 7 | * @time 2016年9月6日 8 | * @modifytime 9 | */ 10 | public class ManagerRPC { 11 | 12 | 13 | private Integer managerType; // 1 禁用 2 降级 3解禁 4取消降级 5 审核通过 14 | private String host; //host 15 | private int port; //port 16 | private String serviceName; //服务名 17 | private Integer serviceState;//服务状态 18 | private int weightVal; //权重 19 | 20 | public Integer getManagerType() { 21 | return managerType; 22 | } 23 | 24 | public void setManagerType(Integer managerType) { 25 | this.managerType = managerType; 26 | } 27 | 28 | public String getHost() { 29 | return host; 30 | } 31 | 32 | public void setHost(String host) { 33 | this.host = host; 34 | } 35 | 36 | public int getPort() { 37 | return port; 38 | } 39 | 40 | public void setPort(int port) { 41 | this.port = port; 42 | } 43 | 44 | public String getServiceName() { 45 | return serviceName; 46 | } 47 | 48 | public void setServiceName(String serviceName) { 49 | this.serviceName = serviceName; 50 | } 51 | 52 | public Integer getServiceState() { 53 | return serviceState; 54 | } 55 | 56 | public void setServiceState(Integer serviceState) { 57 | this.serviceState = serviceState; 58 | } 59 | 60 | public int getWeightVal() { 61 | return weightVal; 62 | } 63 | 64 | public void setWeightVal(int weightVal) { 65 | this.weightVal = weightVal; 66 | } 67 | 68 | @Override 69 | public String toString() { 70 | return "ManagerRPC [managerType=" + managerType + ", host=" + host + ", port=" + port + ", serviceName=" + serviceName + ", serviceState=" 71 | + serviceState + ", weightVal=" + weightVal + "]"; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /laopopo-registry-default/src/main/java/org/laopopo/base/registry/RegistryServerConfig.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.base.registry; 2 | 3 | import java.io.File; 4 | 5 | import org.laopopo.common.loadbalance.LoadBalanceStrategy; 6 | import org.laopopo.common.rpc.ServiceReviewState; 7 | 8 | /** 9 | * 10 | * @author BazingaLyn 11 | * @description 注册中心的一些基本配置文件 12 | * @time 2016年9月8日 13 | * @modifytime 14 | */ 15 | public class RegistryServerConfig { 16 | 17 | //持久化保存的位置 18 | private String storePathRootDir = System.getProperty("user.home") + File.separator + "test" + File.separator + "serviceInfo.json"; 19 | //每个多久时间刷盘到硬盘上,默认30s 20 | private int persistTime = 30; 21 | //默认的负载均衡策略 22 | private LoadBalanceStrategy defaultLoadBalanceStrategy = LoadBalanceStrategy.WEIGHTINGRANDOM; 23 | //默认的审核状态,默认状态是未审核,测试的时候可以修改成审核通过 24 | private ServiceReviewState defaultReviewState = ServiceReviewState.HAS_NOT_REVIEWED; 25 | 26 | public String getStorePathRootDir() { 27 | return storePathRootDir; 28 | } 29 | 30 | public void setStorePathRootDir(String storePathRootDir) { 31 | this.storePathRootDir = storePathRootDir; 32 | } 33 | 34 | public int getPersistTime() { 35 | return persistTime; 36 | } 37 | 38 | public void setPersistTime(int persistTime) { 39 | this.persistTime = persistTime; 40 | } 41 | 42 | public LoadBalanceStrategy getDefaultLoadBalanceStrategy() { 43 | return defaultLoadBalanceStrategy; 44 | } 45 | 46 | public void setDefaultLoadBalanceStrategy(LoadBalanceStrategy defaultLoadBalanceStrategy) { 47 | this.defaultLoadBalanceStrategy = defaultLoadBalanceStrategy; 48 | } 49 | 50 | public ServiceReviewState getDefaultReviewState() { 51 | return defaultReviewState; 52 | } 53 | 54 | public void setDefaultReviewState(ServiceReviewState defaultReviewState) { 55 | this.defaultReviewState = defaultReviewState; 56 | } 57 | 58 | 59 | } 60 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/netty/example_1/NettyTransporterTest1.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.netty.example_1; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.laopopo.common.exception.remoting.RemotingCommmonCustomException; 7 | import org.laopopo.common.transport.body.CommonCustomBody; 8 | import org.laopopo.remoting.model.RemotingTransporter; 9 | 10 | public class NettyTransporterTest1 { 11 | 12 | public static final byte STUDENTS = 1; 13 | public static final byte TEACHER = 2; 14 | 15 | public static void main(String[] args) { 16 | 17 | 18 | StudentInfos infos = new StudentInfos(); 19 | //学生信息 20 | @SuppressWarnings("unused") 21 | RemotingTransporter studentsRemotingTransporter = RemotingTransporter.createRequestTransporter(STUDENTS, infos); 22 | //学生信息 23 | TeacherInfo info = new TeacherInfo(); 24 | @SuppressWarnings("unused") 25 | RemotingTransporter teacherRemotingTransporter = RemotingTransporter.createRequestTransporter(TEACHER, info); 26 | } 27 | 28 | private static class StudentInfos implements CommonCustomBody { 29 | 30 | List students = new ArrayList(); 31 | 32 | @Override 33 | public void checkFields() throws RemotingCommmonCustomException { 34 | } 35 | 36 | public List getStudents() { 37 | return students; 38 | } 39 | 40 | public void setStudents(List students) { 41 | this.students = students; 42 | } 43 | 44 | } 45 | 46 | private static class TeacherInfo implements CommonCustomBody { 47 | 48 | String teacher = ""; 49 | 50 | @Override 51 | public void checkFields() throws RemotingCommmonCustomException { 52 | } 53 | 54 | public String getTeacher() { 55 | return teacher; 56 | } 57 | 58 | public void setTeacher(String teacher) { 59 | this.teacher = teacher; 60 | } 61 | 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/provider/DefaultProviderRegistryProcessor.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.provider; 2 | 3 | import static org.laopopo.common.protocal.LaopopoProtocol.AUTO_DEGRADE_SERVICE; 4 | import static org.laopopo.common.protocal.LaopopoProtocol.DEGRADE_SERVICE; 5 | import io.netty.channel.ChannelHandlerContext; 6 | 7 | import org.laopopo.remoting.ConnectionUtils; 8 | import org.laopopo.remoting.model.NettyRequestProcessor; 9 | import org.laopopo.remoting.model.RemotingTransporter; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | /** 14 | * 15 | * @author BazingaLyn 16 | * @description provider端注册的处理器 17 | * @time 18 | * @modifytime 19 | */ 20 | public class DefaultProviderRegistryProcessor implements NettyRequestProcessor { 21 | 22 | private static final Logger logger = LoggerFactory.getLogger(DefaultProviderRegistryProcessor.class); 23 | 24 | private DefaultProvider defaultProvider; 25 | 26 | public DefaultProviderRegistryProcessor(DefaultProvider defaultProvider) { 27 | this.defaultProvider = defaultProvider; 28 | } 29 | 30 | @Override 31 | public RemotingTransporter processRequest(ChannelHandlerContext ctx, RemotingTransporter request) throws Exception { 32 | 33 | if (logger.isDebugEnabled()) { 34 | logger.debug("receive request, {} {} {}",// 35 | request.getCode(), // 36 | ConnectionUtils.parseChannelRemoteAddr(ctx.channel()), // 37 | request); 38 | } 39 | 40 | switch (request.getCode()) { 41 | case DEGRADE_SERVICE: 42 | return this.defaultProvider.handlerDegradeServiceRequest(request,ctx.channel(),DEGRADE_SERVICE); 43 | case AUTO_DEGRADE_SERVICE: 44 | return this.defaultProvider.handlerDegradeServiceRequest(request,ctx.channel(),AUTO_DEGRADE_SERVICE); 45 | } 46 | return null; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/persist/FastjsonTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.persist; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.util.List; 6 | 7 | import org.laopopo.common.rpc.MetricsReporter; 8 | import org.laopopo.common.utils.PersistUtils; 9 | 10 | import com.alibaba.fastjson.JSON; 11 | 12 | public class FastjsonTest { 13 | 14 | 15 | private static String storePathRootDir = System.getProperty("user.home") + File.separator + "test" + File.separator + "historyMetrics.json"; 16 | public static void main(String[] args) throws IOException { 17 | 18 | 19 | String existStr = PersistUtils.file2String(storePathRootDir); 20 | 21 | List metricsReporters = JSON.parseArray(existStr.trim(), MetricsReporter.class); 22 | 23 | for(MetricsReporter s :metricsReporters){ 24 | System.out.println(s); 25 | } 26 | 27 | // 28 | // 29 | // 30 | // 31 | // 32 | // Student student1 = new Student(1, "王诩文", 26); 33 | // Student student2 = new Student(2, "朴俊", 27); 34 | // Student student3 = new Student(3, "陆维梁", 28); 35 | // Student student4 = new Student(4, "曾卓", 28); 36 | // List students = new ArrayList(); 37 | // students.add(student1); 38 | // students.add(student2); 39 | // students.add(student3); 40 | // students.add(student4); 41 | // //json to str 42 | // String str = JSON.toJSONString(students); 43 | // 44 | // //获取到自定义的用户名 45 | // String fileName = storePathRootDir; 46 | // 47 | // PersistUtils.string2File(str, fileName); 48 | // 49 | // String existStr = PersistUtils.file2String(fileName); 50 | // 51 | // List recoverStudents =JSON.parseArray(existStr.trim(), Student.class); 52 | // 53 | // System.out.println(recoverStudents); 54 | // 55 | // for(Student s :recoverStudents){ 56 | // System.out.println(s); 57 | // } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/netty/encode/RemotingTransporterEncoder.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.netty.encode; 2 | 3 | import static org.laopopo.common.protocal.LaopopoProtocol.MAGIC; 4 | import static org.laopopo.common.serialization.SerializerHolder.serializerImpl; 5 | import io.netty.buffer.ByteBuf; 6 | import io.netty.channel.ChannelHandler; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.handler.codec.MessageToByteEncoder; 9 | 10 | import java.io.IOException; 11 | 12 | import org.laopopo.common.protocal.LaopopoProtocol; 13 | import org.laopopo.remoting.model.RemotingTransporter; 14 | 15 | /** 16 | * 17 | * @author BazingaLyn 18 | * @description Netty 对{@link RemotingTransporter}的编码器 19 | * @time 2016年8月10日 20 | * @modifytime 21 | */ 22 | @ChannelHandler.Sharable 23 | public class RemotingTransporterEncoder extends MessageToByteEncoder { 24 | 25 | 26 | @Override 27 | protected void encode(ChannelHandlerContext ctx, RemotingTransporter msg, ByteBuf out) throws IOException { 28 | doEncodeRemotingTransporter(msg, out); 29 | } 30 | 31 | private void doEncodeRemotingTransporter(RemotingTransporter msg, ByteBuf out) throws IOException { 32 | byte[] body = serializerImpl().writeObject(msg.getCustomHeader()); 33 | 34 | 35 | byte isCompress = LaopopoProtocol.UNCOMPRESS; 36 | // if(body.length > 1024){ //经过测试,压缩之后的效率低于不压缩 37 | // isCompress = LaopopoProtocol.COMPRESS; 38 | // body = Snappy.compress(body); 39 | // } 40 | 41 | out.writeShort(MAGIC). //协议头 42 | writeByte(msg.getTransporterType())// 传输类型 sign 是请求还是响应 43 | .writeByte(msg.getCode()) // 请求类型requestcode 表明主题信息的类型,也代表请求的类型 44 | .writeLong(msg.getOpaque()) //requestId 45 | .writeInt(body.length) //length 46 | .writeByte(isCompress) //是否压缩 47 | .writeBytes(body); 48 | 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/utils/Status.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.utils; 2 | 3 | public enum Status { 4 | 5 | OK( (byte) 0x20, "OK"), // 正常 - 请求已完成 6 | CLIENT_ERROR( (byte) 0x30, "CLIENT_ERROR"), // 内部错误 — 因为意外情况, 客户端不能发送请求 7 | CLIENT_TIMEOUT( (byte) 0x31, "CLIENT_TIMEOUT"), // 超时 - 客户端超时 8 | SERVER_TIMEOUT( (byte) 0x32, "SERVER_TIMEOUT"), // 超时 - 服务端超时 9 | BAD_REQUEST( (byte) 0x40, "BAD_REQUEST"), // 错误请求 — 请求中有语法问题, 或不能满足请求 10 | SERVICE_NOT_FOUND( (byte) 0x44, "SERVICE_NOT_FOUND"), // 找不到 - 指定服务不存在 11 | SERVER_ERROR( (byte) 0x50, "SERVER_ERROR"), // 内部错误 — 因为意外情况, 服务器不能完成请求 12 | // SERVER_BUSY( (byte) 0x51, "SERVER_BUSY"), // 内部错误 — 服务器太忙, 无法处理新的请求 13 | SERVICE_ERROR( (byte) 0x52, "SERVICE_ERROR"), // 服务错误 - 服务执行意外出错 14 | APP_FLOW_CONTROL( (byte) 0x53, "APP_FLOW_CONTROL"), // 服务错误 - App级别服务限流 15 | PROVIDER_FLOW_CONTROL( (byte) 0x54, "PROVIDER_FLOW_CONTROL"); // 服务错误 - Provider级别服务限流 16 | 17 | Status(byte value, String description) { 18 | this.value = value; 19 | this.description = description; 20 | } 21 | 22 | private byte value; 23 | private String description; 24 | 25 | public static Status parse(byte value) { 26 | for (Status s : values()) { 27 | if (s.value == value) { 28 | return s; 29 | } 30 | } 31 | return null; 32 | } 33 | 34 | public byte value() { 35 | return value; 36 | } 37 | 38 | public String description() { 39 | return description; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return description(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/utils/NamedThreadFactory.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.utils; 2 | 3 | import java.util.concurrent.ThreadFactory; 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | public class NamedThreadFactory implements ThreadFactory { 10 | 11 | private static final Logger logger = LoggerFactory.getLogger(NamedThreadFactory.class); 12 | 13 | private static final AtomicInteger poolId = new AtomicInteger(); 14 | 15 | private final AtomicInteger nextId = new AtomicInteger(); 16 | private final String prefix; 17 | private final boolean daemon; 18 | private final ThreadGroup group; 19 | 20 | public NamedThreadFactory() { 21 | this("pool-" + poolId.incrementAndGet(), false); 22 | } 23 | 24 | public NamedThreadFactory(String prefix) { 25 | this(prefix, false); 26 | } 27 | 28 | public NamedThreadFactory(String prefix, boolean daemon) { 29 | this.prefix = prefix + " #"; 30 | this.daemon = daemon; 31 | SecurityManager s = System.getSecurityManager(); 32 | group = (s == null) ? Thread.currentThread().getThreadGroup() : s.getThreadGroup(); 33 | } 34 | 35 | public Thread newThread(Runnable r) { 36 | 37 | String name = prefix + nextId.getAndIncrement(); 38 | Thread t = new Thread(group, r, name, 0); 39 | try { 40 | if (t.isDaemon()) { 41 | if (!daemon) { 42 | t.setDaemon(false); 43 | } 44 | } else { 45 | if (daemon) { 46 | t.setDaemon(true); 47 | } 48 | } 49 | } catch (Exception ignored) { /* Doesn't matter even if failed to set. */ } 50 | 51 | logger.debug("Creates new {}.", t); 52 | 53 | return t; 54 | } 55 | 56 | public ThreadGroup getThreadGroup() { 57 | return group; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_3/MonitorTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_3; 2 | 3 | import java.util.concurrent.ConcurrentMap; 4 | 5 | import org.laopopo.common.rpc.MetricsReporter; 6 | import org.laopopo.common.rpc.RegisterMeta.Address; 7 | import org.laopopo.monitor.DefaultMonitor; 8 | import org.laopopo.monitor.MonitorConfig; 9 | import org.laopopo.remoting.netty.NettyServerConfig; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | public class MonitorTest { 14 | 15 | private static final Logger logger = LoggerFactory.getLogger(MonitorTest.class); 16 | 17 | private static DefaultMonitor defaultMonitor = null; 18 | 19 | public static void main(String[] args) { 20 | 21 | Thread t = new Thread(new MonitorTest1Scanner(), "timeout.scanner"); 22 | t.setDaemon(true); 23 | t.start(); 24 | 25 | NettyServerConfig config = new NettyServerConfig(); 26 | MonitorConfig monitorConfig = new MonitorConfig(); 27 | // 注册中心的端口号 28 | config.setListenPort(19010); 29 | 30 | defaultMonitor = new DefaultMonitor(config,monitorConfig); 31 | defaultMonitor.start(); 32 | 33 | } 34 | 35 | private static class MonitorTest1Scanner implements Runnable { 36 | 37 | @Override 38 | public void run() { 39 | 40 | for (;;) { 41 | logger.info("统计中"); 42 | try { 43 | Thread.sleep(10000); 44 | ConcurrentMap> maps = defaultMonitor.getGlobalMetricsReporter(); 45 | if(null != maps){ 46 | for(String serviceName : maps.keySet()){ 47 | if(maps.get(serviceName) != null){ 48 | for(Address address : maps.get(serviceName).keySet()){ 49 | logger.info("serviceName [{}] address [{}] and metricsInfo [{}]",serviceName,address,maps.get(serviceName).get(address)); 50 | } 51 | } 52 | } 53 | } 54 | } catch (InterruptedException e) { 55 | e.printStackTrace(); 56 | } 57 | 58 | } 59 | } 60 | 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/provider/Provider.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.provider; 2 | 3 | import io.netty.channel.Channel; 4 | 5 | import org.laopopo.common.exception.remoting.RemotingException; 6 | import org.laopopo.remoting.model.RemotingTransporter; 7 | 8 | 9 | /** 10 | * 11 | * @author BazingaLyn 12 | * @description provider端的接口 13 | * 服务提供者端需要提供以下接口 14 | * 1)需要暴露哪些服务【必要】{@link Provider #publishService(Object...)} 15 | * 2)暴露的服务在哪个端口上提供【必要】{@link Provider #serviceListenAddress(String)} 16 | * 3)设置注册中心的地址【必要】{@link Provider #registryAddress(String)} 17 | * 4)暴露启动服务提供者的方法【必须调用】{@link Provider #start()} 18 | * 5)设置provider端提供的监控地址【非必要】{@link Provider #monitorAddress(String)} 19 | * @time 2016年8月16日 20 | * @modifytime 2016年8月23日 21 | */ 22 | public interface Provider { 23 | 24 | /** 25 | * 启动provider的实例 26 | * @throws RemotingException 27 | * @throws InterruptedException 28 | */ 29 | void start() throws InterruptedException, RemotingException; 30 | 31 | 32 | /** 33 | * 发布服务 34 | * @throws InterruptedException 35 | * @throws RemotingException 36 | */ 37 | void publishedAndStartProvider() throws InterruptedException, RemotingException; 38 | 39 | 40 | /** 41 | * 暴露服务的地址 42 | * @param port 43 | * @return 44 | */ 45 | Provider serviceListenPort(int exposePort); 46 | 47 | 48 | 49 | /** 50 | * 设置注册中心的地址 host:port,host1:port1 51 | * @param registryAddress 52 | * @return 53 | */ 54 | Provider registryAddress(String registryAddress); 55 | 56 | 57 | 58 | /** 59 | * 监控中心的地址,不是强依赖,不设置也没有关系 60 | * @param monitorAddress 61 | * @return 62 | */ 63 | Provider monitorAddress(String monitorAddress); 64 | 65 | /** 66 | * 需要暴露的实例 67 | * @param obj 68 | */ 69 | Provider publishService(Object ...obj); 70 | 71 | 72 | /** 73 | * 处理消费者的rpc请求 74 | * @param request 75 | * @param channel 76 | * @return 77 | */ 78 | void handlerRPCRequest(RemotingTransporter request, Channel channel); 79 | 80 | 81 | } 82 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/transport/body/ResponseCustomBody.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.transport.body; 2 | 3 | import static org.laopopo.common.utils.Status.OK; 4 | 5 | import org.laopopo.common.exception.remoting.RemotingCommmonCustomException; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | /** 10 | * 11 | * @author BazingaLyn 12 | * @description 13 | * @time 2016年8月20日 14 | * @modifytime 2016年9月20日 15 | */ 16 | public class ResponseCustomBody implements CommonCustomBody { 17 | 18 | private static final Logger logger = LoggerFactory.getLogger(ResponseCustomBody.class); 19 | 20 | private byte status = OK.value(); 21 | 22 | private ResultWrapper resultWrapper; 23 | 24 | public ResponseCustomBody(byte status, ResultWrapper resultWrapper) { 25 | this.status = status; 26 | this.resultWrapper = resultWrapper; 27 | } 28 | 29 | public byte getStatus() { 30 | return status; 31 | } 32 | 33 | public void setStatus(byte status) { 34 | this.status = status; 35 | } 36 | 37 | public ResultWrapper getResultWrapper() { 38 | return resultWrapper; 39 | } 40 | 41 | public void setResultWrapper(ResultWrapper resultWrapper) { 42 | this.resultWrapper = resultWrapper; 43 | } 44 | 45 | @Override 46 | public void checkFields() throws RemotingCommmonCustomException { 47 | } 48 | 49 | public static class ResultWrapper { 50 | 51 | private Object result; 52 | private String error; 53 | 54 | public Object getResult() { 55 | return result; 56 | } 57 | 58 | public void setResult(Object result) { 59 | this.result = result; 60 | } 61 | 62 | public String getError() { 63 | return error; 64 | } 65 | 66 | public void setError(String error) { 67 | this.error = error; 68 | } 69 | } 70 | 71 | public Object getResult() { 72 | 73 | if(status == OK.value()){ 74 | return getResultWrapper().getResult(); 75 | }else{ 76 | logger.warn("get result occor exception [{}]",getResultWrapper().getError()); 77 | return null; 78 | } 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /laopopo-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.bazinga 8 | laopopo 9 | 1.0.0 10 | 11 | laopopo-example 12 | laopopo-example 13 | http://maven.apache.org 14 | 15 | 16 | 17 | 18 | ${project.groupId} 19 | laopopo-common 20 | 21 | 22 | ${project.groupId} 23 | laopopo-remoting 24 | 25 | 26 | ${project.groupId} 27 | laopopo-registry-default 28 | 29 | 30 | ${project.groupId} 31 | laopopo-client 32 | 33 | 34 | ${project.groupId} 35 | laopopo-monitor 36 | 37 | 38 | ${project.groupId} 39 | laopopo-spring-support 40 | 41 | 42 | com.alibaba 43 | fastjson 44 | 45 | 46 | org.xerial.snappy 47 | snappy-java 48 | 49 | 50 | ch.qos.logback 51 | logback-classic 52 | 1.0.13 53 | 54 | 55 | org.springframework 56 | spring-context 57 | provided 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/provider/flow/control/ServiceFlowController.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.provider.flow.control; 2 | 3 | import java.util.concurrent.atomic.AtomicLong; 4 | 5 | import org.laopopo.common.utils.SystemClock; 6 | 7 | /** 8 | * 9 | * @author BazingaLyn 10 | * @description 服务限流控制器 11 | * @time 12 | * @modifytime 13 | */ 14 | public class ServiceFlowController { 15 | 16 | private AtomicLong[] metricses = new AtomicLong[] { new AtomicLong(0), new AtomicLong(0), new AtomicLong(0) }; 17 | 18 | public long incrementAtCurrentMinute() { 19 | 20 | long currentTime = SystemClock.millisClock().now(); 21 | int index = (int) ((currentTime / 60000) % 3); 22 | 23 | AtomicLong atomicLong = metricses[index]; 24 | return atomicLong.incrementAndGet(); 25 | 26 | } 27 | 28 | public long getCurrentCallCountAtLastMinute() { 29 | 30 | long currentTime = SystemClock.millisClock().now(); 31 | int index = (int) (((currentTime / 60000)) % 3); 32 | AtomicLong atomicLong = metricses[index]; 33 | return atomicLong.get(); 34 | 35 | } 36 | 37 | public long getLastCallCountAtLastMinute() { 38 | 39 | long currentTime = SystemClock.millisClock().now(); 40 | int index = (int) (((currentTime / 60000) - 1) % 3); 41 | AtomicLong atomicLong = metricses[index]; 42 | return atomicLong.get(); 43 | 44 | } 45 | 46 | 47 | public long getNextMinuteCallCount() { 48 | 49 | long currentTime = SystemClock.millisClock().now(); 50 | int index = (int) (((currentTime / 60000) + 1) % 3); 51 | AtomicLong atomicLong = metricses[index]; 52 | return atomicLong.get(); 53 | 54 | } 55 | 56 | public void clearNextMinuteCallCount() { 57 | 58 | long currentTime = SystemClock.millisClock().now(); 59 | int index = (int) (((currentTime / 60000) + 1) % 3); 60 | AtomicLong atomicLong = metricses[index]; 61 | atomicLong.set(0); 62 | } 63 | 64 | public AtomicLong[] getMetricses() { 65 | return metricses; 66 | } 67 | 68 | public void setMetricses(AtomicLong[] metricses) { 69 | this.metricses = metricses; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/utils/SystemClock.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.utils; 2 | 3 | import static java.util.concurrent.TimeUnit.MILLISECONDS; 4 | 5 | import java.util.concurrent.Executors; 6 | import java.util.concurrent.ScheduledExecutorService; 7 | import java.util.concurrent.ThreadFactory; 8 | import java.util.concurrent.atomic.AtomicLong; 9 | 10 | /** 11 | * {@link SystemClock} is a optimized substitute of {@link System#currentTimeMillis()} for avoiding context switch overload. 12 | * 13 | * Every instance would start a thread to update the time, so it's supposed to be singleton in application context. 14 | * 15 | * Forked from https://github.com/zhongl/jtoolkit/blob/master/common/src/main/java/com/github/zhongl/jtoolkit/SystemClock.java 16 | */ 17 | public class SystemClock { 18 | 19 | private static final SystemClock millisClock = new SystemClock(1); 20 | 21 | private final long precision; 22 | private final AtomicLong now; 23 | 24 | public static SystemClock millisClock() { 25 | return millisClock; 26 | } 27 | 28 | private SystemClock(long precision) { 29 | this.precision = precision; 30 | now = new AtomicLong(System.currentTimeMillis()); 31 | scheduleClockUpdating(); 32 | } 33 | 34 | private void scheduleClockUpdating() { 35 | ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { 36 | 37 | public Thread newThread(Runnable runnable) { 38 | Thread t = new Thread(runnable, "system.clock"); 39 | t.setDaemon(true); 40 | return t; 41 | } 42 | }); 43 | 44 | scheduler.scheduleAtFixedRate(new Runnable() { 45 | 46 | public void run() { 47 | now.set(System.currentTimeMillis()); 48 | } 49 | }, precision, precision, MILLISECONDS); 50 | } 51 | 52 | public long now() { 53 | return now.get(); 54 | } 55 | 56 | public long precision() { 57 | return precision; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /laopopo-registry-default/src/main/java/org/laopopo/base/registry/model/RegistryPersistRecord.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.base.registry.model; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import org.laopopo.common.loadbalance.LoadBalanceStrategy; 7 | import org.laopopo.common.rpc.RegisterMeta.Address; 8 | import org.laopopo.common.rpc.ServiceReviewState; 9 | 10 | /** 11 | * 12 | * @author BazingaLyn 13 | * @description 注册中心的记录的数据去持久化的数据 14 | * @time 2016年9月8日 15 | * @modifytime 16 | */ 17 | public class RegistryPersistRecord { 18 | 19 | private String serviceName; 20 | 21 | private LoadBalanceStrategy balanceStrategy; 22 | 23 | private List providerInfos = new ArrayList(); 24 | 25 | public RegistryPersistRecord() { 26 | } 27 | 28 | public String getServiceName() { 29 | return serviceName; 30 | } 31 | 32 | public void setServiceName(String serviceName) { 33 | this.serviceName = serviceName; 34 | } 35 | 36 | public LoadBalanceStrategy getBalanceStrategy() { 37 | return balanceStrategy; 38 | } 39 | 40 | public void setBalanceStrategy(LoadBalanceStrategy balanceStrategy) { 41 | this.balanceStrategy = balanceStrategy; 42 | } 43 | 44 | public List getProviderInfos() { 45 | return providerInfos; 46 | } 47 | 48 | public void setProviderInfos(List providerInfos) { 49 | this.providerInfos = providerInfos; 50 | } 51 | 52 | 53 | public static class PersistProviderInfo { 54 | 55 | private Address address; 56 | 57 | private ServiceReviewState isReviewed = ServiceReviewState.PASS_REVIEW; 58 | 59 | public PersistProviderInfo() { 60 | } 61 | 62 | public Address getAddress() { 63 | return address; 64 | } 65 | 66 | public void setAddress(Address address) { 67 | this.address = address; 68 | } 69 | 70 | public ServiceReviewState getIsReviewed() { 71 | return isReviewed; 72 | } 73 | 74 | public void setIsReviewed(ServiceReviewState isReviewed) { 75 | this.isReviewed = isReviewed; 76 | } 77 | 78 | 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /laopopo-spring-support/src/main/java/org/laopopo/spring/support/LaopopoSpringProviderBean.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.spring.support; 2 | 3 | import org.laopopo.client.provider.DefaultProvider; 4 | import org.springframework.beans.factory.InitializingBean; 5 | 6 | /** 7 | * 8 | * @author BazingaLyn 9 | * @description 服务提供者对spring的支持 10 | * @time 2016年10月17日 11 | * @modifytime 2016年10月19日 12 | */ 13 | public class LaopopoSpringProviderBean implements InitializingBean { 14 | 15 | 16 | private DefaultProvider defaultProvider; 17 | private String registryAddress; 18 | private String monitorAddress; 19 | private int listenerPort; 20 | private Object[] publishObjs; 21 | 22 | @Override 23 | public void afterPropertiesSet() throws Exception { 24 | 25 | if(registryAddress != null){ 26 | defaultProvider.registryAddress(registryAddress); 27 | } 28 | 29 | if(monitorAddress != null){ 30 | defaultProvider.monitorAddress(monitorAddress); 31 | } 32 | 33 | defaultProvider.serviceListenPort(listenerPort); 34 | 35 | defaultProvider.publishService(publishObjs); 36 | 37 | defaultProvider.start(); 38 | 39 | } 40 | 41 | public String getRegistryAddress() { 42 | return registryAddress; 43 | } 44 | 45 | public void setRegistryAddress(String registryAddress) { 46 | this.registryAddress = registryAddress; 47 | } 48 | 49 | public String getMonitorAddress() { 50 | return monitorAddress; 51 | } 52 | 53 | public void setMonitorAddress(String monitorAddress) { 54 | this.monitorAddress = monitorAddress; 55 | } 56 | 57 | public int getListenerPort() { 58 | return listenerPort; 59 | } 60 | 61 | public void setListenerPort(int listenerPort) { 62 | this.listenerPort = listenerPort; 63 | } 64 | 65 | public Object[] getPublishObjs() { 66 | return publishObjs; 67 | } 68 | 69 | public void setPublishObjs(Object[] publishObjs) { 70 | this.publishObjs = publishObjs; 71 | } 72 | 73 | public DefaultProvider getDefaultProvider() { 74 | return defaultProvider; 75 | } 76 | 77 | public void setDefaultProvider(DefaultProvider defaultProvider) { 78 | this.defaultProvider = defaultProvider; 79 | } 80 | 81 | 82 | } 83 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/consumer/DefaultConsumerRegistryProcessor.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.consumer; 2 | 3 | import static org.laopopo.common.protocal.LaopopoProtocol.SUBCRIBE_RESULT; 4 | import static org.laopopo.common.protocal.LaopopoProtocol.SUBCRIBE_SERVICE_CANCEL; 5 | import static org.laopopo.common.protocal.LaopopoProtocol.CHANGE_LOADBALANCE; 6 | import io.netty.channel.ChannelHandlerContext; 7 | 8 | import org.laopopo.remoting.ConnectionUtils; 9 | import org.laopopo.remoting.model.NettyRequestProcessor; 10 | import org.laopopo.remoting.model.RemotingTransporter; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | /** 15 | * 16 | * @author BazingaLyn 17 | * @description 消费者端注册功能的主要处理逻辑 18 | * @time 2016年8月22日 19 | * @modifytime 20 | */ 21 | public class DefaultConsumerRegistryProcessor implements NettyRequestProcessor { 22 | 23 | private static final Logger logger = LoggerFactory.getLogger(DefaultConsumerRegistryProcessor.class); 24 | 25 | private DefaultConsumer defaultConsumer; 26 | 27 | public DefaultConsumerRegistryProcessor(DefaultConsumer defaultConsumer) { 28 | this.defaultConsumer = defaultConsumer; 29 | } 30 | 31 | @Override 32 | public RemotingTransporter processRequest(ChannelHandlerContext ctx, RemotingTransporter request) throws Exception { 33 | 34 | if (logger.isDebugEnabled()) { 35 | logger.debug("receive request, {} {} {}",// 36 | request.getCode(), // 37 | ConnectionUtils.parseChannelRemoteAddr(ctx.channel()), // 38 | request); 39 | } 40 | 41 | switch (request.getCode()) { 42 | case SUBCRIBE_RESULT: 43 | // 回复ack信息 这个也要保持幂等性,因为有可能在consumer消费成功之后发送ack信息到registry信息丢失,registry回重新发送订阅结果信息 44 | return this.defaultConsumer.getConsumerManager().handlerSubcribeResult(request, ctx.channel()); 45 | case SUBCRIBE_SERVICE_CANCEL: 46 | // 回复ack信息 47 | return this.defaultConsumer.getConsumerManager().handlerSubscribeResultCancel(request, ctx.channel()); 48 | case CHANGE_LOADBALANCE: 49 | // 回复ack信息 50 | return this.defaultConsumer.getConsumerManager().handlerServiceLoadBalance(request, ctx.channel()); 51 | } 52 | 53 | return null; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/rpc/MetricsReporter.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.rpc; 2 | 3 | import java.io.Serializable; 4 | 5 | 6 | /** 7 | * 8 | * @author BazingaLyn 9 | * @description 统计报告 10 | * @time 2016年8月30日 11 | * @modifytime 12 | */ 13 | public class MetricsReporter implements Serializable { 14 | 15 | /** 16 | * 17 | */ 18 | private static final long serialVersionUID = -3846340000197732373L; 19 | 20 | private String host; //host 21 | private int port; //端口号 22 | private String serviceName; //统计的服务名 23 | private Long callCount = 0l; //调用的次数 24 | private Long failCount = 0l; //失败的次数 25 | private Long requestSize = 0l; //请求的大小 26 | private Long totalReuqestTime = 0l; //总请求的时间 27 | 28 | 29 | public String getServiceName() { 30 | return serviceName; 31 | } 32 | public void setServiceName(String serviceName) { 33 | this.serviceName = serviceName; 34 | } 35 | public Long getCallCount() { 36 | return callCount; 37 | } 38 | public void setCallCount(Long callCount) { 39 | this.callCount = callCount; 40 | } 41 | public Long getFailCount() { 42 | return failCount; 43 | } 44 | public void setFailCount(Long failCount) { 45 | this.failCount = failCount; 46 | } 47 | public String getHost() { 48 | return host; 49 | } 50 | public void setHost(String host) { 51 | this.host = host; 52 | } 53 | public int getPort() { 54 | return port; 55 | } 56 | public void setPort(int port) { 57 | this.port = port; 58 | } 59 | public Long getRequestSize() { 60 | return requestSize; 61 | } 62 | public void setRequestSize(Long requestSize) { 63 | this.requestSize = requestSize; 64 | } 65 | public Long getTotalReuqestTime() { 66 | return totalReuqestTime; 67 | } 68 | public void setTotalReuqestTime(Long totalReuqestTime) { 69 | this.totalReuqestTime = totalReuqestTime; 70 | } 71 | @Override 72 | public String toString() { 73 | return "MetricsReporter [host=" + host + ", port=" + port + ", serviceName=" + serviceName + ", callCount=" + callCount + ", failCount=" + failCount 74 | + ", requestSize=" + requestSize + ", totalReuqestTime=" + totalReuqestTime + "]"; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/persist/FileToJsonTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.persist; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.List; 8 | 9 | import org.laopopo.common.rpc.MetricsReporter; 10 | import org.laopopo.common.utils.PersistUtils; 11 | 12 | import com.alibaba.fastjson.JSON; 13 | 14 | public class FileToJsonTest { 15 | 16 | private static String storePathRootDir = System.getProperty("user.home") + File.separator + "test" + File.separator + "historyMetrics.json"; 17 | 18 | 19 | public static void main(String[] args) { 20 | 21 | String persistString = PersistUtils.file2String(storePathRootDir); 22 | 23 | if(null != persistString){ 24 | @SuppressWarnings("unchecked") 25 | List metricsReporters = JSON.parseObject(persistString.trim(), List.class); 26 | for(MetricsReporter metricsReporter : metricsReporters){ 27 | System.out.println(metricsReporter); 28 | } 29 | // ConcurrentMap> objects = JSON.parseObject(persistString.trim(), ConcurrentMap.class); 30 | // 31 | // for(String service: objects.keySet()){ 32 | // System.out.println(service); 33 | // ConcurrentMap concurrentMap = objects.get(service); 34 | // for(Address address : concurrentMap.keySet()){ 35 | // System.out.println(address); 36 | // System.out.println(concurrentMap.get(address)); 37 | // } 38 | // 39 | // } 40 | } 41 | 42 | } 43 | 44 | public static final String file2String(final String fileName) { 45 | // 读取txt内容为字符串 46 | StringBuffer txtContent = new StringBuffer(); 47 | // 每次读取的byte数 48 | byte[] b = new byte[8 * 1024]; 49 | InputStream in = null; 50 | try { 51 | // 文件输入流 52 | in = new FileInputStream(fileName); 53 | while (in.read(b) != -1) { 54 | // 字符串拼接 55 | txtContent.append(new String(b)); 56 | } 57 | // 关闭流 58 | in.close(); 59 | } catch (Exception e) { 60 | } finally { 61 | if (in != null) { 62 | try { 63 | in.close(); 64 | } catch (IOException e) { 65 | } 66 | } 67 | } 68 | return txtContent.toString(); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/serialization/proto/ProtoStuffSerializer.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.serialization.proto; 2 | 3 | import io.protostuff.LinkedBuffer; 4 | import io.protostuff.ProtostuffIOUtil; 5 | import io.protostuff.Schema; 6 | import io.protostuff.runtime.RuntimeSchema; 7 | 8 | import java.util.Map; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | 11 | import org.laopopo.common.serialization.Serializer; 12 | import org.objenesis.Objenesis; 13 | import org.objenesis.ObjenesisStd; 14 | 15 | /** 16 | * 17 | * @author BazingaLyn 18 | * @description 使用protoStuff序列化 19 | * 序列化的对象不需要实现java.io.Serializable 也不需要有默认的构造函数 20 | * @time 2016年8月12日 21 | * @modifytime 22 | */ 23 | public class ProtoStuffSerializer implements Serializer { 24 | 25 | private static Map, Schema> cachedSchema = new ConcurrentHashMap, Schema>(); 26 | 27 | private static Objenesis objenesis = new ObjenesisStd(true); 28 | 29 | @SuppressWarnings("unchecked") 30 | public byte[] writeObject(T obj) { 31 | 32 | Class cls = (Class) obj.getClass(); 33 | LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); 34 | try { 35 | Schema schema = getSchema(cls); 36 | return ProtostuffIOUtil.toByteArray(obj, schema, buffer); 37 | } catch (Exception e) { 38 | throw new IllegalStateException(e.getMessage(), e); 39 | } finally { 40 | buffer.clear(); 41 | } 42 | } 43 | 44 | public T readObject(byte[] bytes, Class clazz) { 45 | try { 46 | T message = objenesis.newInstance(clazz); 47 | Schema schema = getSchema(clazz); 48 | ProtostuffIOUtil.mergeFrom(bytes, message, schema); 49 | return message; 50 | } catch (Exception e) { 51 | throw new IllegalStateException(e.getMessage(), e); 52 | } 53 | } 54 | 55 | @SuppressWarnings("unchecked") 56 | private static Schema getSchema(Class cls) { 57 | Schema schema = (Schema) cachedSchema.get(cls); 58 | if (schema == null) { 59 | schema = RuntimeSchema.createFrom(cls); 60 | cachedSchema.put(cls, schema); 61 | } 62 | return schema; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/netty/NettyServerConfig.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.netty; 2 | 3 | import static org.laopopo.common.utils.Constants.AVAILABLE_PROCESSORS; 4 | 5 | 6 | public class NettyServerConfig implements Cloneable{ 7 | 8 | private int listenPort = 8888; 9 | 10 | private int serverWorkerThreads = AVAILABLE_PROCESSORS << 1; 11 | 12 | private int channelInactiveHandlerThreads = 1; 13 | 14 | private int serverSocketSndBufSize = -1; 15 | 16 | private int serverSocketRcvBufSize = -1; 17 | 18 | private int writeBufferLowWaterMark = -1; 19 | private int writeBufferHighWaterMark = -1; 20 | 21 | public int getListenPort() { 22 | return listenPort; 23 | } 24 | 25 | public void setListenPort(int listenPort) { 26 | this.listenPort = listenPort; 27 | } 28 | 29 | public int getServerWorkerThreads() { 30 | return serverWorkerThreads; 31 | } 32 | 33 | public void setServerWorkerThreads(int serverWorkerThreads) { 34 | this.serverWorkerThreads = serverWorkerThreads; 35 | } 36 | 37 | 38 | public int getChannelInactiveHandlerThreads() { 39 | return channelInactiveHandlerThreads; 40 | } 41 | 42 | public void setChannelInactiveHandlerThreads(int channelInactiveHandlerThreads) { 43 | this.channelInactiveHandlerThreads = channelInactiveHandlerThreads; 44 | } 45 | 46 | public int getServerSocketSndBufSize() { 47 | return serverSocketSndBufSize; 48 | } 49 | 50 | public void setServerSocketSndBufSize(int serverSocketSndBufSize) { 51 | this.serverSocketSndBufSize = serverSocketSndBufSize; 52 | } 53 | 54 | public int getServerSocketRcvBufSize() { 55 | return serverSocketRcvBufSize; 56 | } 57 | 58 | public void setServerSocketRcvBufSize(int serverSocketRcvBufSize) { 59 | this.serverSocketRcvBufSize = serverSocketRcvBufSize; 60 | } 61 | 62 | public int getWriteBufferLowWaterMark() { 63 | return writeBufferLowWaterMark; 64 | } 65 | 66 | public void setWriteBufferLowWaterMark(int writeBufferLowWaterMark) { 67 | this.writeBufferLowWaterMark = writeBufferLowWaterMark; 68 | } 69 | 70 | public int getWriteBufferHighWaterMark() { 71 | return writeBufferHighWaterMark; 72 | } 73 | 74 | public void setWriteBufferHighWaterMark(int writeBufferHighWaterMark) { 75 | this.writeBufferHighWaterMark = writeBufferHighWaterMark; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/netty/RemotingClient.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.netty; 2 | 3 | import java.util.concurrent.ExecutorService; 4 | 5 | import org.laopopo.common.exception.remoting.RemotingException; 6 | import org.laopopo.common.exception.remoting.RemotingSendRequestException; 7 | import org.laopopo.common.exception.remoting.RemotingTimeoutException; 8 | import org.laopopo.remoting.model.NettyChannelInactiveProcessor; 9 | import org.laopopo.remoting.model.NettyRequestProcessor; 10 | import org.laopopo.remoting.model.RemotingTransporter; 11 | 12 | /** 13 | * 14 | * @author BazingaLyn 15 | * @description Netty客户端的一些特定的方法 16 | * @time 2016年8月10日 17 | * @modifytime 18 | */ 19 | public interface RemotingClient extends BaseRemotingService { 20 | 21 | /** 22 | * 向某个地址发送request的请求,并且远程端返回 #RemotingTransporter的结果,调用超时时间是timeoutMillis 23 | * @param addr 远程地址 例如 127.0.0.1:8080 24 | * @param request 请求入参 详细参考 #RemotingTransporter 25 | * @param timeoutMillis 超时时间 26 | * @return 27 | * @throws RemotingTimeoutException 28 | * @throws RemotingSendRequestException 29 | * @throws InterruptedException 30 | * @throws RemotingException 31 | */ 32 | public RemotingTransporter invokeSync(final String addr ,final RemotingTransporter request,final long timeoutMillis) throws RemotingTimeoutException, RemotingSendRequestException, InterruptedException, RemotingException; 33 | 34 | /** 35 | * 注入处理器,例如某个Netty的Client实例,这个实例是Consumer端的,它需要处理订阅返回的信息 36 | * 假如订阅的requestCode 是100,那么给定requestCode特定的处理器processorA,且指定该处理器的线程执行器是executorA 37 | * 这样做的好处就是业务逻辑很清晰,什么样的业务请求对应特定的处理器 38 | * 一般场景下,不是高并发的场景下,executor是可以复用的,这样减少线程上下文的切换 39 | * @param requestCode 40 | * @param processor 41 | * @param executor 42 | */ 43 | void registerProcessor(final byte requestCode, final NettyRequestProcessor processor, final ExecutorService executor); 44 | 45 | 46 | /** 47 | * 注册channel inactive的处理器 48 | * @param processor 49 | * @param executor 50 | */ 51 | void registerChannelInactiveProcessor(NettyChannelInactiveProcessor processor, ExecutorService executor); 52 | 53 | /** 54 | * 某个地址的长连接的channel是否可写 55 | * @param addr 56 | * @return 57 | */ 58 | boolean isChannelWriteable(final String addr); 59 | 60 | 61 | /** 62 | * 当与server的channel inactive的时候,是否主动重连netty的server端 63 | * @param isReconnect 64 | */ 65 | void setreconnect(boolean isReconnect); 66 | 67 | } 68 | -------------------------------------------------------------------------------- /laopopo-registry-default/src/main/java/org/laopopo/base/registry/DefaultRegistryProcessor.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.base.registry; 2 | 3 | import static org.laopopo.common.protocal.LaopopoProtocol.MANAGER_SERVICE; 4 | import static org.laopopo.common.protocal.LaopopoProtocol.PUBLISH_CANCEL_SERVICE; 5 | import static org.laopopo.common.protocal.LaopopoProtocol.PUBLISH_SERVICE; 6 | import static org.laopopo.common.protocal.LaopopoProtocol.SUBSCRIBE_SERVICE; 7 | import io.netty.channel.ChannelHandlerContext; 8 | 9 | import org.laopopo.remoting.ConnectionUtils; 10 | import org.laopopo.remoting.model.NettyRequestProcessor; 11 | import org.laopopo.remoting.model.RemotingTransporter; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | /** 16 | * 17 | * @author BazingaLyn 18 | * @description 注册中心的处理转换器 19 | * @time 2016年8月13日 20 | * @modifytime 2016年8月31日 21 | */ 22 | public class DefaultRegistryProcessor implements NettyRequestProcessor { 23 | 24 | private static final Logger logger = LoggerFactory.getLogger(DefaultRegistryProcessor.class); 25 | 26 | private DefaultRegistryServer defaultRegistryServer; 27 | 28 | public DefaultRegistryProcessor(DefaultRegistryServer defaultRegistryServer) { 29 | this.defaultRegistryServer = defaultRegistryServer; 30 | } 31 | 32 | @Override 33 | public RemotingTransporter processRequest(ChannelHandlerContext ctx, RemotingTransporter request) throws Exception { 34 | 35 | if (logger.isDebugEnabled()) { 36 | logger.debug("receive request, {} {} {}",// 37 | request.getCode(), // 38 | ConnectionUtils.parseChannelRemoteAddr(ctx.channel()), // 39 | request); 40 | } 41 | 42 | switch (request.getCode()) { 43 | 44 | case PUBLISH_SERVICE: // 处理服务提供者provider推送的服务信息 45 | return this.defaultRegistryServer.getProviderManager().handlerRegister(request, ctx.channel()); // 要保持幂等性,同一个实例重复发布同一个服务的时候对于注册中心来说是无影响的 46 | case PUBLISH_CANCEL_SERVICE: // 处理服务提供者provider推送的服务取消的信息 47 | return this.defaultRegistryServer.getProviderManager().handlerRegisterCancel(request, ctx.channel()); 48 | case SUBSCRIBE_SERVICE: // 处理服务消费者consumer订阅服务的请求 49 | return this.defaultRegistryServer.getProviderManager().handleSubscribe(request, ctx.channel()); 50 | case MANAGER_SERVICE: // 处理管理者发送过来的服务管理服务 51 | return this.defaultRegistryServer.getProviderManager().handleManager(request, ctx.channel()); 52 | } 53 | 54 | return null; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /laopopo-console/src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Laopopo-monitor 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 37 | 38 |
39 |
40 |
41 |
42 |
43 | 44 | 45 | 46 | 47 |
48 |
49 |
50 | 51 |
52 |
53 |
54 | 55 | 56 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/transport/body/RequestReviewCustomBody.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.transport.body; 2 | 3 | import org.laopopo.common.exception.remoting.RemotingCommmonCustomException; 4 | 5 | /** 6 | * 7 | * @author BazingaLyn 8 | * @description 注册中心向monitor发送该请求是否审核的请求体 9 | * @time 2016年8月15日 10 | * @modifytime 11 | */ 12 | public class RequestReviewCustomBody implements CommonCustomBody { 13 | 14 | // 地址 15 | private String host; 16 | // 端口 17 | private int port; 18 | // 组别 19 | private String group; 20 | // 版本信息 21 | private String version; 22 | // 服务名 23 | private String serviceProviderName; 24 | // 是否该服务是VIP服务,如果该服务是VIP服务,走特定的channel,也可以有降级的服务 25 | private boolean isVIPService; 26 | 27 | 28 | public RequestReviewCustomBody(String host, int port, String group, String version, String serviceProviderName, boolean isVIPService) { 29 | this.host = host; 30 | this.port = port; 31 | this.group = group; 32 | this.version = version; 33 | this.serviceProviderName = serviceProviderName; 34 | this.isVIPService = isVIPService; 35 | } 36 | 37 | @Override 38 | public void checkFields() throws RemotingCommmonCustomException { 39 | } 40 | 41 | public String getHost() { 42 | return host; 43 | } 44 | 45 | public void setHost(String host) { 46 | this.host = host; 47 | } 48 | 49 | public int getPort() { 50 | return port; 51 | } 52 | 53 | public void setPort(int port) { 54 | this.port = port; 55 | } 56 | 57 | public String getGroup() { 58 | return group; 59 | } 60 | 61 | public void setGroup(String group) { 62 | this.group = group; 63 | } 64 | 65 | public String getVersion() { 66 | return version; 67 | } 68 | 69 | public void setVersion(String version) { 70 | this.version = version; 71 | } 72 | 73 | public String getServiceProviderName() { 74 | return serviceProviderName; 75 | } 76 | 77 | public void setServiceProviderName(String serviceProviderName) { 78 | this.serviceProviderName = serviceProviderName; 79 | } 80 | 81 | public boolean isVIPService() { 82 | return isVIPService; 83 | } 84 | 85 | public void setVIPService(boolean isVIPService) { 86 | this.isVIPService = isVIPService; 87 | } 88 | 89 | @Override 90 | public String toString() { 91 | return "RequestReviewResultCommonCustomBody [host=" + host + ", port=" + port + ", group=" + group + ", version=" + version + ", serviceProviderName=" 92 | + serviceProviderName + ", isVIPService=" + isVIPService + "]"; 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /laopopo-registry-default/src/main/java/org/laopopo/base/registry/DefaultRegistryChannelInactiveProcessor.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.base.registry; 2 | 3 | import io.netty.channel.Channel; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.util.AttributeKey; 6 | import io.netty.util.internal.ConcurrentSet; 7 | 8 | import org.laopopo.common.exception.remoting.RemotingSendRequestException; 9 | import org.laopopo.common.exception.remoting.RemotingTimeoutException; 10 | import org.laopopo.common.rpc.RegisterMeta; 11 | import org.laopopo.common.rpc.RegisterMeta.Address; 12 | import org.laopopo.remoting.model.NettyChannelInactiveProcessor; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | /** 17 | * 18 | * @author BazingaLyn 19 | * @description 当provider发生异常的时候注册中心需要做的处理 20 | * @time 2016年8月15日 21 | * @modifytime 22 | */ 23 | public class DefaultRegistryChannelInactiveProcessor implements NettyChannelInactiveProcessor { 24 | 25 | private static final Logger logger = LoggerFactory.getLogger(DefaultRegistryChannelInactiveProcessor.class); 26 | 27 | private DefaultRegistryServer defaultRegistryServer; 28 | 29 | private static final AttributeKey> S_PUBLISH_KEY = AttributeKey.valueOf("server.published"); 30 | 31 | public DefaultRegistryChannelInactiveProcessor(DefaultRegistryServer defaultRegistryServer) { 32 | this.defaultRegistryServer = defaultRegistryServer; 33 | } 34 | 35 | @Override 36 | public void processChannelInactive(ChannelHandlerContext ctx) throws RemotingSendRequestException, RemotingTimeoutException, InterruptedException { 37 | //获取到当前的channel,此时的channel应该是打过记号的 38 | Channel channel = ctx.channel(); 39 | 40 | // 取消之前发布的所有服务 41 | ConcurrentSet registerMetaSet = channel.attr(S_PUBLISH_KEY).get(); 42 | 43 | //如果该channel打过的记号是空,或者是空集合的话,直接返回 44 | if (registerMetaSet == null || registerMetaSet.isEmpty()) { 45 | logger.debug("registerMetaSet is empty"); 46 | return; 47 | } 48 | //接下来需要做两件事情 49 | //1 修改当前注册中心该channel所提供的所有服务取消 50 | //2 发送请求告之consumer该地址对应的所有服务下线 51 | 52 | Address address = null; 53 | for (RegisterMeta meta : registerMetaSet) { 54 | if (address == null) { 55 | address = meta.getAddress(); 56 | } 57 | this.defaultRegistryServer.getProviderManager().handlePublishCancel(meta, channel); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/netty/TestCommonCustomBody.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.netty; 2 | 3 | import java.io.Serializable; 4 | 5 | import org.laopopo.common.exception.remoting.RemotingCommmonCustomException; 6 | import org.laopopo.common.transport.body.CommonCustomBody; 7 | 8 | public class TestCommonCustomBody implements CommonCustomBody,Serializable { 9 | 10 | /** 11 | * 12 | */ 13 | private static final long serialVersionUID = 7679994718274344134L; 14 | 15 | private int id; 16 | 17 | private String name; 18 | 19 | private ComplexTestObj complexTestObj; 20 | 21 | public TestCommonCustomBody() { 22 | } 23 | 24 | public TestCommonCustomBody(int id, String name, ComplexTestObj complexTestObj) { 25 | this.id = id; 26 | this.name = name; 27 | this.complexTestObj = complexTestObj; 28 | } 29 | 30 | 31 | public ComplexTestObj getComplexTestObj() { 32 | return complexTestObj; 33 | } 34 | 35 | public void setComplexTestObj(ComplexTestObj complexTestObj) { 36 | this.complexTestObj = complexTestObj; 37 | } 38 | 39 | public int getId() { 40 | return id; 41 | } 42 | 43 | public void setId(int id) { 44 | this.id = id; 45 | } 46 | 47 | public String getName() { 48 | return name; 49 | } 50 | 51 | public void setName(String name) { 52 | this.name = name; 53 | } 54 | 55 | @Override 56 | public void checkFields() throws RemotingCommmonCustomException { 57 | 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return "TestCommonCustomBody [id=" + id + ", name=" + name + ", complexTestObj=" + complexTestObj + "]"; 63 | } 64 | 65 | public static class ComplexTestObj implements Serializable { 66 | 67 | /** 68 | * 69 | */ 70 | private static final long serialVersionUID = 5694424296393939225L; 71 | 72 | private String attr1; 73 | 74 | private Integer attr2; 75 | 76 | public ComplexTestObj() { 77 | } 78 | 79 | public ComplexTestObj(String attr1, Integer attr2) { 80 | super(); 81 | this.attr1 = attr1; 82 | this.attr2 = attr2; 83 | } 84 | 85 | 86 | public String getAttr1() { 87 | return attr1; 88 | } 89 | 90 | public void setAttr1(String attr1) { 91 | this.attr1 = attr1; 92 | } 93 | 94 | public Integer getAttr2() { 95 | return attr2; 96 | } 97 | 98 | public void setAttr2(Integer attr2) { 99 | this.attr2 = attr2; 100 | } 101 | 102 | @Override 103 | public String toString() { 104 | return "ComplexTestObj [attr1=" + attr1 + ", attr2=" + attr2 + "]"; 105 | } 106 | 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/utils/PersistUtils.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.utils; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.FileWriter; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | 9 | /** 10 | * 11 | * @author BazingaLyn 12 | * @description 持久化工具 13 | * @time 2016年9月1日 14 | * @modifytime 15 | */ 16 | public class PersistUtils { 17 | 18 | 19 | /** 20 | * 将json数据存到某个文件中 21 | * @param str 22 | * @param fileName 23 | * @throws IOException 24 | */ 25 | public static final void string2File(final String str, final String fileName) throws IOException { 26 | String tmpFile = fileName + ".tmp"; 27 | string2FileNotSafe(str, tmpFile); 28 | 29 | String bakFile = fileName + ".bak"; 30 | String prevContent = file2String(fileName); 31 | if (prevContent != null) { 32 | string2FileNotSafe(prevContent, bakFile); 33 | } 34 | 35 | File file = new File(fileName); 36 | file.delete(); 37 | 38 | file = new File(tmpFile); 39 | file.renameTo(new File(fileName)); 40 | } 41 | 42 | public static final void string2FileNotSafe(final String str, final String fileName) throws IOException { 43 | File file = new File(fileName); 44 | File fileParent = file.getParentFile(); 45 | if (fileParent != null) { 46 | fileParent.mkdirs(); 47 | } 48 | FileWriter fileWriter = null; 49 | 50 | try { 51 | fileWriter = new FileWriter(file); 52 | fileWriter.write(str); 53 | } 54 | catch (IOException e) { 55 | throw e; 56 | } 57 | finally { 58 | if (fileWriter != null) { 59 | try { 60 | fileWriter.close(); 61 | } 62 | catch (IOException e) { 63 | throw e; 64 | } 65 | } 66 | } 67 | } 68 | 69 | public static final String file2String(final String fileName) { 70 | // 读取txt内容为字符串 71 | StringBuffer txtContent = new StringBuffer(); 72 | // 每次读取的byte数 73 | byte[] b = new byte[8 * 1024]; 74 | InputStream in = null; 75 | try { 76 | // 文件输入流 77 | in = new FileInputStream(fileName); 78 | while (in.read(b) != -1) { 79 | // 字符串拼接 80 | txtContent.append(new String(b)); 81 | } 82 | // 关闭流 83 | in.close(); 84 | } catch (Exception e) { 85 | return null; 86 | } finally { 87 | if (in != null) { 88 | try { 89 | in.close(); 90 | } catch (IOException e) { 91 | } 92 | } 93 | } 94 | return txtContent.toString(); 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/provider/interceptor/ProviderProxyHandler.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.provider.interceptor; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.concurrent.Callable; 5 | import java.util.concurrent.CopyOnWriteArrayList; 6 | 7 | import net.bytebuddy.implementation.bind.annotation.AllArguments; 8 | import net.bytebuddy.implementation.bind.annotation.Origin; 9 | import net.bytebuddy.implementation.bind.annotation.RuntimeType; 10 | import net.bytebuddy.implementation.bind.annotation.SuperCall; 11 | 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | /** 16 | * 17 | * @author BazingaLyn 18 | * @description 19 | * @time 20 | * @modifytime 21 | */ 22 | public class ProviderProxyHandler { 23 | 24 | private static final Logger logger = LoggerFactory.getLogger(ProviderProxyHandler.class); 25 | 26 | private final CopyOnWriteArrayList interceptors = new CopyOnWriteArrayList(); 27 | 28 | @RuntimeType 29 | public Object invoke(@SuperCall Callable superMethod, 30 | @Origin Method method, 31 | @AllArguments @RuntimeType Object[] args) throws Exception{ 32 | 33 | String methodName = method.getName(); 34 | 35 | for (int i = interceptors.size() - 1; i >= 0; i--) { 36 | ProviderInterceptor interceptor = interceptors.get(i); 37 | try { 38 | interceptor.beforeInvoke(methodName, args); 39 | } catch (Throwable t) { 40 | logger.warn("Interceptor[{}#beforeInvoke]: {}.", interceptor.getClass().getName()); 41 | } 42 | } 43 | Object result = null; 44 | try { 45 | result = superMethod.call(); 46 | } finally { 47 | for (int i = 0; i < interceptors.size(); i++) { 48 | ProviderInterceptor interceptor = interceptors.get(i); 49 | try { 50 | interceptor.afterInvoke(methodName, args, result); 51 | } catch (Throwable t) { 52 | logger.warn("Interceptor[{}#afterInvoke]: {}.", interceptor.getClass().getName()); 53 | } 54 | } 55 | } 56 | return result; 57 | } 58 | 59 | public ProviderProxyHandler withIntercept(ProviderInterceptor interceptor) { 60 | interceptors.add(interceptor); 61 | return this; 62 | } 63 | 64 | public ProviderProxyHandler withIntercept(ProviderInterceptor... interceptors) { 65 | for (ProviderInterceptor interceptor : interceptors) { 66 | withIntercept(interceptor); 67 | } 68 | return this; 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/transport/body/ManagerServiceCustomBody.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.transport.body; 2 | 3 | import org.laopopo.common.exception.remoting.RemotingCommmonCustomException; 4 | import org.laopopo.common.loadbalance.LoadBalanceStrategy; 5 | import org.laopopo.common.rpc.ManagerServiceRequestType; 6 | import org.laopopo.common.rpc.RegisterMeta.Address; 7 | import org.laopopo.common.rpc.ServiceReviewState; 8 | 9 | /** 10 | * 11 | * @author BazingaLyn 12 | * @description 管理者发送给注册中心的修改服务的信息的主体信息 13 | * @time 2016年8月29日 14 | * @modifytime 2016年8月31日 15 | */ 16 | public class ManagerServiceCustomBody implements CommonCustomBody { 17 | 18 | 19 | private ManagerServiceRequestType managerServiceRequestType;//管理的类型 20 | private String serivceName; //服务名 21 | private Address address; //该服务提供的地址 22 | private ServiceReviewState serviceReviewState; //是否审核通过 23 | private boolean isDegradeService; //该服务是否降级 24 | private int weightVal; //该服务的权重 25 | private LoadBalanceStrategy loadBalanceStrategy; //服务访问策略 26 | 27 | @Override 28 | public void checkFields() throws RemotingCommmonCustomException { 29 | } 30 | 31 | public String getSerivceName() { 32 | return serivceName; 33 | } 34 | 35 | public void setSerivceName(String serivceName) { 36 | this.serivceName = serivceName; 37 | } 38 | 39 | public ServiceReviewState getServiceReviewState() { 40 | return serviceReviewState; 41 | } 42 | 43 | public void setServiceReviewState(ServiceReviewState serviceReviewState) { 44 | this.serviceReviewState = serviceReviewState; 45 | } 46 | 47 | public Address getAddress() { 48 | return address; 49 | } 50 | 51 | public void setAddress(Address address) { 52 | this.address = address; 53 | } 54 | 55 | public boolean isDegradeService() { 56 | return isDegradeService; 57 | } 58 | 59 | public void setDegradeService(boolean isDegradeService) { 60 | this.isDegradeService = isDegradeService; 61 | } 62 | 63 | public int getWeightVal() { 64 | return weightVal; 65 | } 66 | 67 | public void setWeightVal(int weightVal) { 68 | this.weightVal = weightVal; 69 | } 70 | 71 | public ManagerServiceRequestType getManagerServiceRequestType() { 72 | return managerServiceRequestType; 73 | } 74 | 75 | public void setManagerServiceRequestType(ManagerServiceRequestType managerServiceRequestType) { 76 | this.managerServiceRequestType = managerServiceRequestType; 77 | } 78 | 79 | public LoadBalanceStrategy getLoadBalanceStrategy() { 80 | return loadBalanceStrategy; 81 | } 82 | 83 | public void setLoadBalanceStrategy(LoadBalanceStrategy loadBalanceStrategy) { 84 | this.loadBalanceStrategy = loadBalanceStrategy; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/utils/NettyChannelGroup.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.utils; 2 | 3 | import io.netty.channel.Channel; 4 | import io.netty.channel.ChannelFuture; 5 | import io.netty.channel.ChannelFutureListener; 6 | 7 | import java.util.concurrent.CopyOnWriteArrayList; 8 | import java.util.concurrent.atomic.AtomicInteger; 9 | 10 | /** 11 | * 12 | * @author BazingaLyn 13 | * @description 14 | * @time 15 | * @modifytime 16 | */ 17 | public class NettyChannelGroup implements ChannelGroup { 18 | 19 | 20 | private final CopyOnWriteArrayList channels = new CopyOnWriteArrayList<>(); 21 | 22 | private AtomicInteger index = new AtomicInteger(0); 23 | 24 | private final UnresolvedAddress address; 25 | 26 | private volatile int weight = 50; 27 | 28 | public NettyChannelGroup(UnresolvedAddress address) { 29 | this.address = address; 30 | } 31 | 32 | @Override 33 | public Channel next() { 34 | for(;;){ 35 | int length = channels.size(); 36 | if(length == 0){ 37 | throw new IllegalStateException("no channel"); 38 | } 39 | if (length == 1) { 40 | return channels.get(0); 41 | } 42 | int offset = Math.abs(index.incrementAndGet() % length); 43 | 44 | return channels.get(offset); 45 | } 46 | } 47 | 48 | @Override 49 | public boolean add(Channel channel) { 50 | boolean added = channels.add(channel); 51 | if (added) { 52 | channel.closeFuture().addListener(remover); 53 | } 54 | return false; 55 | } 56 | 57 | 58 | @Override 59 | public boolean remove(Channel channel) { 60 | return channels.remove(channel); 61 | } 62 | 63 | private final ChannelFutureListener remover = new ChannelFutureListener() { 64 | 65 | @Override 66 | public void operationComplete(ChannelFuture future) throws Exception { 67 | remove(future.channel()); 68 | } 69 | }; 70 | 71 | @Override 72 | public void setWeight(int weight) { 73 | this.weight = weight; 74 | } 75 | 76 | @Override 77 | public int getWeight() { 78 | return weight; 79 | } 80 | 81 | public UnresolvedAddress getAddress() { 82 | return address; 83 | } 84 | 85 | @Override 86 | public int size() { 87 | return channels.size(); 88 | } 89 | 90 | @Override 91 | public boolean isAvailable() { 92 | return channels.size() > 0 ? true : false; 93 | } 94 | 95 | @Override 96 | public String toString() { 97 | return "NettyChannelGroup [channels=" + channels + ", index=" + index + ", address=" + address + ", weight=" + weight + ", remover=" + remover + "]"; 98 | } 99 | 100 | 101 | } 102 | -------------------------------------------------------------------------------- /laopopo-console/src/main/java/org/laopopo/console/web/controller/MonitorCoreController.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.console.web.controller; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import javax.annotation.Resource; 7 | 8 | import org.laopopo.common.rpc.ServiceReviewState; 9 | import org.laopopo.console.info.kaleidoscope.KaleidoscopeInfo; 10 | import org.laopopo.console.model.ManagerRPC; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.stereotype.Controller; 14 | import org.springframework.web.bind.annotation.RequestMapping; 15 | import org.springframework.web.bind.annotation.RequestParam; 16 | import org.springframework.web.bind.annotation.ResponseBody; 17 | 18 | /** 19 | * 20 | * @author BazingaLyn 21 | * @description 管理员管理页面spring mvc的controller TODO 22 | * @time 2016年9月6日 23 | * @modifytime 24 | */ 25 | @Controller 26 | public class MonitorCoreController { 27 | 28 | private static final Logger logger = LoggerFactory.getLogger(MonitorCoreController.class); 29 | 30 | @Resource 31 | private KaleidoscopeInfo kaleidoscopeInfo; 32 | 33 | @ResponseBody 34 | @RequestMapping(value = "/index.do") 35 | // 首页初始化 36 | public Map initTable(@RequestParam Map requestMap) { 37 | int pageSize = 10; 38 | int offset = 1; 39 | try { 40 | pageSize = Integer.valueOf("" + requestMap.get("limit")); // 页大小 41 | } catch (NumberFormatException e) { 42 | logger.info(e.getMessage()); 43 | } 44 | try { 45 | offset = Integer.valueOf("" + requestMap.get("offset")); 46 | } catch (NumberFormatException e) { 47 | logger.info(e.getMessage()); 48 | } 49 | 50 | Map resultMap = kaleidoscopeInfo.findInfoByPage(pageSize, offset); 51 | return resultMap; 52 | } 53 | 54 | @ResponseBody 55 | @RequestMapping(value = "/manager.do") 56 | // 管理请求 57 | public Map managerRpc(ManagerRPC managerRPC) { 58 | Map resultMap = new HashMap(); 59 | 60 | Boolean operationFlag = false; 61 | 62 | // 禁用 63 | if (managerRPC.getManagerType() == 1) { 64 | operationFlag = kaleidoscopeInfo.notifyReviewService(managerRPC.getHost(), managerRPC.getPort(), managerRPC.getServiceName(),ServiceReviewState.FORBIDDEN); 65 | } 66 | // 降级 67 | if (managerRPC.getManagerType() == 2) { 68 | operationFlag = kaleidoscopeInfo.notifyServiceDegrade(managerRPC.getHost(), managerRPC.getPort(), managerRPC.getServiceName()); 69 | } 70 | // 审核通过 71 | if (managerRPC.getManagerType() == 5) { 72 | operationFlag = kaleidoscopeInfo.notifyReviewService(managerRPC.getHost(), managerRPC.getPort(), managerRPC.getServiceName(),ServiceReviewState.PASS_REVIEW); 73 | } 74 | 75 | resultMap.put("status", operationFlag); 76 | return resultMap; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/model/RemotingResponse.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.model; 2 | 3 | import java.util.concurrent.CountDownLatch; 4 | import java.util.concurrent.TimeUnit; 5 | 6 | import org.laopopo.remoting.InvokeCallback; 7 | 8 | /** 9 | * 10 | * @author BazingaLyn 11 | * @description 请求返回的对象包装类 12 | * @time 2016年8月10日11:08:43 13 | * @modifytime 14 | */ 15 | public class RemotingResponse { 16 | 17 | // 远程端返回的结果集 18 | private volatile RemotingTransporter remotingTransporter; 19 | 20 | // 该请求抛出的异常,如果存在的话 21 | private volatile Throwable cause; 22 | // 发送端是否发送成功 23 | private volatile boolean sendRequestOK = true; 24 | 25 | // 请求的opaque 26 | private final long opaque; 27 | 28 | // 默认的回调函数 29 | private final InvokeCallback invokeCallback; 30 | 31 | // 请求的默认超时时间 32 | private final long timeoutMillis; 33 | 34 | private final long beginTimestamp = System.currentTimeMillis(); 35 | private final CountDownLatch countDownLatch = new CountDownLatch(1); 36 | 37 | public RemotingResponse(long opaque, long timeoutMillis, InvokeCallback invokeCallback) { 38 | this.invokeCallback = invokeCallback; 39 | this.opaque = opaque; 40 | this.timeoutMillis = timeoutMillis; 41 | } 42 | 43 | public void executeInvokeCallback() { 44 | if (invokeCallback != null) { 45 | invokeCallback.operationComplete(this); 46 | } 47 | } 48 | 49 | public boolean isSendRequestOK() { 50 | return sendRequestOK; 51 | } 52 | 53 | public void setSendRequestOK(boolean sendRequestOK) { 54 | this.sendRequestOK = sendRequestOK; 55 | } 56 | 57 | public long getOpaque() { 58 | return opaque; 59 | } 60 | 61 | public RemotingTransporter getRemotingTransporter() { 62 | return remotingTransporter; 63 | } 64 | 65 | public void setRemotingTransporter(RemotingTransporter remotingTransporter) { 66 | this.remotingTransporter = remotingTransporter; 67 | } 68 | 69 | public Throwable getCause() { 70 | return cause; 71 | } 72 | 73 | public void setCause(Throwable cause) { 74 | this.cause = cause; 75 | } 76 | 77 | public long getTimeoutMillis() { 78 | return timeoutMillis; 79 | } 80 | 81 | public long getBeginTimestamp() { 82 | return beginTimestamp; 83 | } 84 | 85 | public RemotingTransporter waitResponse() throws InterruptedException{ 86 | this.countDownLatch.await(this.timeoutMillis, TimeUnit.MILLISECONDS); 87 | return this.remotingTransporter; 88 | } 89 | 90 | /** 91 | * 当远程端返回结果的时候,TCP的长连接的上层载体channel 的handler会将其放入与requestId 92 | * 对应的Response中去 93 | * @param remotingTransporter 94 | */ 95 | public void putResponse(final RemotingTransporter remotingTransporter){ 96 | this.remotingTransporter = remotingTransporter; 97 | //接收到对应的消息之后需要countDown 98 | this.countDownLatch.countDown(); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /laopopo-example/src/main/java/org/laopopo/example/generic/test_1/ConsumerTest.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.example.generic.test_1; 2 | 3 | import java.util.concurrent.ConcurrentMap; 4 | import java.util.concurrent.CopyOnWriteArrayList; 5 | 6 | import org.laopopo.client.consumer.Consumer.SubscribeManager; 7 | import org.laopopo.client.consumer.ConsumerClient; 8 | import org.laopopo.client.consumer.ConsumerConfig; 9 | import org.laopopo.common.utils.ChannelGroup; 10 | import org.laopopo.remoting.netty.NettyClientConfig; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | public class ConsumerTest { 15 | 16 | private static final Logger logger = LoggerFactory.getLogger(ConsumerTest.class); 17 | 18 | private static ConsumerClient commonclient; 19 | 20 | public static void main(String[] args) throws Throwable { 21 | 22 | Thread t = new Thread(new SubcribeResultScanner(), "timeout.scanner"); 23 | t.setDaemon(true); 24 | t.start(); 25 | 26 | NettyClientConfig registryNettyClientConfig = new NettyClientConfig(); 27 | registryNettyClientConfig.setDefaultAddress("127.0.0.1:18010"); 28 | 29 | NettyClientConfig provideClientConfig = new NettyClientConfig(); 30 | 31 | ConsumerClient client = new ConsumerClient(registryNettyClientConfig, provideClientConfig, new ConsumerConfig()); 32 | 33 | client.start(); 34 | 35 | commonclient = client; 36 | SubscribeManager subscribeManager = client.subscribeService("LAOPOPO.TEST.SAYHELLO"); 37 | 38 | if (!subscribeManager.waitForAvailable(3000l)) { 39 | throw new Exception("no service provider"); 40 | } 41 | 42 | Object obj = client.call("LAOPOPO.TEST.SAYHELLO", "shine"); 43 | if (obj instanceof String) { 44 | System.out.println((String) obj); 45 | } 46 | 47 | SubscribeManager subscribeManager2 = client.subscribeService("LAOPOPO.TEST.SAYBYE"); 48 | 49 | if (!subscribeManager2.waitForAvailable(3000l)) { 50 | throw new Exception("no service provider"); 51 | } 52 | 53 | Object obj1 = client.call("LAOPOPO.TEST.SAYBYE", "shine"); 54 | if (obj1 instanceof String) { 55 | System.out.println((String) obj1); 56 | } 57 | 58 | } 59 | 60 | private static class SubcribeResultScanner implements Runnable { 61 | 62 | @Override 63 | public void run() { 64 | 65 | for (;;) { 66 | try { 67 | logger.info("统计中"); 68 | Thread.sleep(10000); 69 | 70 | @SuppressWarnings("static-access") 71 | ConcurrentMap> result = commonclient.getGroups(); 72 | if(result != null){ 73 | for(String serviceName:result.keySet()){ 74 | System.out.println(serviceName); 75 | for(ChannelGroup channelGroup :result.get(serviceName)){ 76 | System.out.println(channelGroup.toString()); 77 | } 78 | } 79 | } 80 | } catch (Throwable t) { 81 | logger.error("An exception has been caught while scanning the timeout acknowledges {}.", t); 82 | } 83 | } 84 | } 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /laopopo-common/src/main/java/org/laopopo/common/protocal/LaopopoProtocol.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.common.protocal; 2 | 3 | 4 | /** 5 | * 6 | * @author BazingaLyn 7 | * @description 网络传输的协议头信息 8 | * @time 2016年8月9日 9 | * @modifytime 10 | */ 11 | public class LaopopoProtocol { 12 | 13 | /** 协议头长度 */ 14 | public static final int HEAD_LENGTH = 16; 15 | 16 | /** Magic */ 17 | public static final short MAGIC = (short) 0xbabe; 18 | 19 | /** 发送的是请求信息*/ 20 | public static final byte REQUEST_REMOTING = 1; 21 | 22 | /** 发送的是响应信息*/ 23 | public static final byte RESPONSE_REMOTING = 2; 24 | 25 | 26 | public static final byte RPC_REMOTING = 3; 27 | 28 | public static final byte HANDLER_ERROR = -1; 29 | 30 | public static final byte HANDLER_BUSY = -2; 31 | 32 | //provider端向registry发送注册信息的code 33 | public static final byte PUBLISH_SERVICE = 65; 34 | //consumer端向registry订阅服务后返回的订阅结果 35 | public static final byte SUBCRIBE_RESULT = 66; 36 | //订阅服务取消 37 | public static final byte SUBCRIBE_SERVICE_CANCEL = 67; 38 | //取消发布服务 39 | public static final byte PUBLISH_CANCEL_SERVICE = 68; 40 | //consumer发送给registry注册服务 41 | public static final byte SUBSCRIBE_SERVICE = 69; 42 | //管理服务的请求 43 | public static final byte MANAGER_SERVICE = 70; 44 | //远程调用的请求 45 | public static final byte RPC_REQUEST = 72; 46 | //降级 47 | public static final byte DEGRADE_SERVICE = 73; 48 | //自动降级 49 | public static final byte AUTO_DEGRADE_SERVICE = 74; 50 | //调用调用的响应 51 | public static final byte RPC_RESPONSE = 75; 52 | //修改负载策略 53 | public static final byte CHANGE_LOADBALANCE = 76; 54 | //统计信息 55 | public static final byte MERTRICS_SERVICE = 77; 56 | //心跳 57 | public static final byte HEARTBEAT = 127; 58 | //ACK 59 | public static final byte ACK = 126; 60 | 61 | public static final byte COMPRESS = 80; 62 | 63 | public static final byte UNCOMPRESS = 81; 64 | 65 | 66 | private byte type; 67 | private byte sign; 68 | private long id; 69 | private int bodyLength; 70 | private byte compress; 71 | 72 | public byte type() { 73 | return type; 74 | } 75 | 76 | public void type(byte type) { 77 | this.type = type; 78 | } 79 | 80 | public byte sign() { 81 | return sign; 82 | } 83 | 84 | public void sign(byte sign) { 85 | this.sign = sign; 86 | } 87 | 88 | public long id() { 89 | return id; 90 | } 91 | 92 | public void id(long id) { 93 | this.id = id; 94 | } 95 | 96 | public int bodyLength() { 97 | return bodyLength; 98 | } 99 | 100 | public void bodyLength(int bodyLength) { 101 | this.bodyLength = bodyLength; 102 | } 103 | 104 | public byte compress() { 105 | return compress; 106 | } 107 | 108 | public void setCompress(byte compress) { 109 | this.compress = compress; 110 | } 111 | 112 | 113 | } 114 | -------------------------------------------------------------------------------- /laopopo-client/src/main/java/org/laopopo/client/metrics/ServiceMeterManager.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.client.metrics; 2 | 3 | import java.util.concurrent.ConcurrentHashMap; 4 | import java.util.concurrent.ConcurrentMap; 5 | 6 | /** 7 | * 8 | * @author BazingaLyn 9 | * @description 服务统计管理 10 | * @time 2016年9月18日 11 | * @modifytime 12 | */ 13 | public class ServiceMeterManager { 14 | 15 | //key是serviceName 16 | private static ConcurrentMap globalMeterManager = new ConcurrentHashMap(); 17 | 18 | /** 19 | * 计算某个服务的调用成功率,四舍五入到个位数 20 | * @param serviceName 21 | * @return 22 | */ 23 | public static Integer calcServiceSuccessRate(String serviceName){ 24 | 25 | Meter meter = globalMeterManager.get(serviceName); 26 | 27 | if(meter == null){ 28 | return 0; 29 | } 30 | 31 | int callCount = meter.getCallCount().intValue(); 32 | int failCount = meter.getFailedCount().intValue(); 33 | 34 | //如果调用的此时是0.默认成功率是100% 35 | if(callCount == 0){ 36 | return 100; 37 | } 38 | 39 | return (100 *(callCount - failCount ) / callCount); 40 | 41 | } 42 | 43 | 44 | /** 45 | * 增加一次调用次数 46 | * @param serviceName 47 | */ 48 | public static void incrementCallTimes(String serviceName){ 49 | 50 | Meter meter = globalMeterManager.get(serviceName); 51 | 52 | if(meter == null){ 53 | meter = new Meter(serviceName); 54 | globalMeterManager.put(serviceName, meter); 55 | } 56 | meter.getCallCount().incrementAndGet(); 57 | 58 | } 59 | 60 | /** 61 | * 增加一次调用失败次数 62 | * @param serviceName 63 | */ 64 | public static void incrementFailTimes(String serviceName){ 65 | 66 | Meter meter = globalMeterManager.get(serviceName); 67 | 68 | if(meter == null){ 69 | meter = new Meter(serviceName); 70 | globalMeterManager.put(serviceName, meter); 71 | } 72 | meter.getFailedCount().incrementAndGet(); 73 | } 74 | 75 | /** 76 | * 累加某个服务的调用时间 77 | * @param serviceName 78 | * @param byteSize 79 | */ 80 | public static void incrementTotalTime(String serviceName,Long timecost){ 81 | 82 | Meter meter = globalMeterManager.get(serviceName); 83 | 84 | if(meter == null){ 85 | meter = new Meter(serviceName); 86 | globalMeterManager.put(serviceName, meter); 87 | } 88 | meter.getTotalCallTime().addAndGet(timecost); 89 | } 90 | 91 | /** 92 | * 累加某个服务的请求入参的大小 93 | * @param serviceName 94 | * @param byteSize 95 | */ 96 | public static void incrementRequestSize(String serviceName,int byteSize){ 97 | 98 | Meter meter = globalMeterManager.get(serviceName); 99 | 100 | if(meter == null){ 101 | meter = new Meter(serviceName); 102 | globalMeterManager.put(serviceName, meter); 103 | } 104 | meter.getTotalRequestSize().addAndGet(byteSize); 105 | } 106 | 107 | 108 | public static void scheduledSendReport() { 109 | } 110 | 111 | public static ConcurrentMap getGlobalMeterManager() { 112 | return globalMeterManager; 113 | } 114 | 115 | 116 | } 117 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/netty/decode/RemotingTransporterDecoder.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting.netty.decode; 2 | 3 | import static org.laopopo.common.protocal.LaopopoProtocol.MAGIC; 4 | import io.netty.buffer.ByteBuf; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.handler.codec.ReplayingDecoder; 7 | 8 | import java.util.List; 9 | 10 | import org.laopopo.common.exception.remoting.RemotingContextException; 11 | import org.laopopo.common.protocal.LaopopoProtocol; 12 | import org.laopopo.remoting.model.RemotingTransporter; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import org.xerial.snappy.Snappy; 16 | 17 | /** 18 | * 19 | * @author BazingaLyn 20 | * @description Netty 对{@link RemotingTransporter}的解码器 21 | * @time 2016年8月10日 22 | * @modifytime 23 | */ 24 | public class RemotingTransporterDecoder extends ReplayingDecoder { 25 | 26 | private static final Logger logger = LoggerFactory.getLogger(RemotingTransporterDecoder.class); 27 | 28 | private static final int MAX_BODY_SIZE = 1024 * 1024 * 5; 29 | 30 | private final LaopopoProtocol header = new LaopopoProtocol(); 31 | 32 | public RemotingTransporterDecoder() { 33 | //设置(下文#state()的默认返回对象) 34 | super(State.HEADER_MAGIC); 35 | } 36 | 37 | @Override 38 | protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) throws Exception { 39 | switch (state()) { 40 | case HEADER_MAGIC: 41 | checkMagic(in.readShort()); // MAGIC 42 | checkpoint(State.HEADER_TYPE); 43 | case HEADER_TYPE : 44 | header.type(in.readByte()); 45 | checkpoint(State.HEADER_SIGN); 46 | case HEADER_SIGN: 47 | header.sign(in.readByte()); // 消息标志位 48 | checkpoint(State.HEADER_ID); 49 | case HEADER_ID: 50 | header.id(in.readLong()); // 消息id 51 | checkpoint(State.HEADER_BODY_LENGTH); 52 | case HEADER_BODY_LENGTH: 53 | header.bodyLength(in.readInt()); // 消息体长度 54 | checkpoint(State.HEADER_COMPRESS); 55 | case HEADER_COMPRESS: 56 | header.setCompress(in.readByte()); // 消息是否压缩 57 | checkpoint(State.BODY); 58 | case BODY: 59 | int bodyLength = checkBodyLength(header.bodyLength()); 60 | byte[] bytes = new byte[bodyLength]; 61 | in.readBytes(bytes); 62 | if(header.compress() == LaopopoProtocol.COMPRESS){ 63 | bytes = Snappy.uncompress(bytes); 64 | } 65 | out.add(RemotingTransporter.newInstance(header.id(), header.sign(),header.type(), bytes)); 66 | break; 67 | default: 68 | break; 69 | } 70 | checkpoint(State.HEADER_MAGIC); 71 | } 72 | 73 | private int checkBodyLength(int bodyLength) throws RemotingContextException { 74 | if (bodyLength > MAX_BODY_SIZE) { 75 | throw new RemotingContextException("body of request is bigger than limit value "+ MAX_BODY_SIZE); 76 | } 77 | return bodyLength; 78 | } 79 | 80 | private void checkMagic(short magic) throws RemotingContextException { 81 | if (MAGIC != magic) { 82 | logger.error("Magic is not match"); 83 | throw new RemotingContextException("magic value is not equal "+MAGIC); 84 | } 85 | } 86 | 87 | enum State { 88 | HEADER_MAGIC, HEADER_TYPE, HEADER_SIGN, HEADER_ID, HEADER_BODY_LENGTH,HEADER_COMPRESS, BODY 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /laopopo-remoting/src/main/java/org/laopopo/remoting/ConnectionUtils.java: -------------------------------------------------------------------------------- 1 | package org.laopopo.remoting; 2 | 3 | import io.netty.channel.Channel; 4 | import io.netty.channel.ChannelFuture; 5 | import io.netty.channel.ChannelFutureListener; 6 | 7 | import java.net.InetSocketAddress; 8 | import java.net.SocketAddress; 9 | 10 | import org.laopopo.common.rpc.RegisterMeta.Address; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | /** 15 | * 16 | * @author BazingaLyn 17 | * @description 18 | * @time 19 | * @modifytime 20 | */ 21 | public class ConnectionUtils { 22 | 23 | private static final Logger logger = LoggerFactory.getLogger(ConnectionUtils.class); 24 | 25 | public static String parseChannelRemoteAddr(final Channel channel) { 26 | if (null == channel) { 27 | return ""; 28 | } 29 | final SocketAddress remote = channel.remoteAddress(); 30 | final String addr = remote != null ? remote.toString() : ""; 31 | 32 | if (addr.length() > 0) { 33 | int index = addr.lastIndexOf("/"); 34 | if (index >= 0) { 35 | return addr.substring(index + 1); 36 | } 37 | 38 | return addr; 39 | } 40 | 41 | return ""; 42 | } 43 | 44 | public static Address parseChannelRemoteAddress(final Channel channel) { 45 | String address = parseChannelRemoteAddr(channel); 46 | if("".equals(address)){ 47 | return null; 48 | } 49 | String[] strs = address.split(":"); 50 | return new Address(strs[0], Integer.parseInt(strs[1])); 51 | 52 | } 53 | 54 | public static SocketAddress string2SocketAddress(String addr) { 55 | String[] s = addr.split(":"); 56 | InetSocketAddress isa = new InetSocketAddress(s[0], Integer.valueOf(s[1])); 57 | return isa; 58 | } 59 | 60 | public static void closeChannel(Channel channel) { 61 | final String addrRemote = parseChannelRemoteAddr(channel); 62 | channel.close().addListener(new ChannelFutureListener() { 63 | @Override 64 | public void operationComplete(ChannelFuture future) throws Exception { 65 | logger.info("closeChannel: close the connection to remote address[{}] result: {}", addrRemote, 66 | future.isSuccess()); 67 | } 68 | }); 69 | 70 | } 71 | 72 | public static String exceptionSimpleDesc(Exception e) { 73 | StringBuffer sb = new StringBuffer(); 74 | if (e != null) { 75 | sb.append(e.toString()); 76 | 77 | StackTraceElement[] stackTrace = e.getStackTrace(); 78 | if (stackTrace != null && stackTrace.length > 0) { 79 | StackTraceElement elment = stackTrace[0]; 80 | sb.append(", "); 81 | sb.append(elment.toString()); 82 | } 83 | } 84 | 85 | return sb.toString(); 86 | } 87 | 88 | public static int getPortFromAddress(String serviceListenAddress) { 89 | int port = 0; 90 | if(null != serviceListenAddress){ 91 | String[] strs = serviceListenAddress.split(":"); 92 | if(strs.length == 2){ 93 | port = Integer.parseInt(strs[1]); 94 | } 95 | } 96 | return port; 97 | } 98 | } 99 | --------------------------------------------------------------------------------