概述
motan是一套高性能、易于使用的分布式远程服务调用(RPC)框架。
功能
支持通过spring配置方式集成,无需额外编写代码即可为服务提供分布式调用能力。
支持集成consul、zookeeper等配置服务组件,提供集群环境的服务发现及治理能力。
支持动态自定义负载均衡、跨机房流量调整等高级服务调度能力。
基于高并发、高负载场景进行优化,保障生产环境下RPC服务高可用。
文档索引
HTTPCLIENT请求基于NETTY的HTTP服务器,NETTY生成相关的HTTPREQUEST、HTTPRESPONSE,调用SPRING 的DISPATCHSERVLET.SERVICE,将HTTPRESPONSE生成二进制字节,返回HTTPCLIENT。DISPATCHSERVLET同时会调用SPRING的CONTROLLER干活,即以前的SPRING MVC那套可以保留。
缺点:
nginx+tomcat与netty优缺点
http://www.oschina.net/question/1765708_158026我的架构最开始是 nginx +
[netty (tcp)
] 用nginx做负载均衡。后来分布式接口变成了http restful -> nginx +
[netty(http)
]于是参考了netty的官方http例子,开始移植代码,其实移植量不大,只需要把原来的tpc handler里面的逻辑放到http handler里面就可以了。本以为ok了,测试才发现了大量的问题,其实问题本身是由于对http基础掌握的还不够透彻,比如keep-alive属性,这个平时基本不用的东西,当你要自己开发http server时,变的很有用,你不能每次都close channel.你要化很多时间了解header里面每个字段的意思,然后去实现它。再比如一个post请求,你要自己写代码从body里面读数据,解码等。
最终我放弃了netty,回到了tomcat.应为tomcat把http的一切都帮你搞定了。
最终的架构是 nginx +
[tomcat(http)
]tomcat就是针对http层的,所以我建议http还是选择tomcat(或者其他成熟的http-server),并不是说netty不好,而是你的选择问题,netty是一个网络组件,tcp,udp,http都可以弄,但是官方文档都是些hello wolrd级别的。如果你非常了解http结构,完全可以基于netty搞出一个比tomcat牛的http server.
如果做tcp开发,netty不二之选!
dubboss是一个分布式REST服务的框架,实现了如下功能:
- 基于dubbo的RPC
- 基于netty的应用服务器
- 基于springmvc的REST调用
- 基于ngnix的负载均衡
https://github.com/leiguorui/dubboss
摘要: 安装第一台tigase服务器安装tigase服务器所需环境。[root@tigase3~]# yum install java-1.7.0-openjdk.x86_64 java-1.7.0-openjdk-devel.x86_64下载tigase服务器软件包。[root@tigase3tmp]#wget https://projects.tigase.org/attachments/d...
阅读全文
http://dubbo.io/User+Guide-zh.htm
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进。

- 单一应用架构
- 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。
- 此时,用于简化增删改查工作量的 数据访问框架(ORM) 是关键。
- 垂直应用架构
- 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。
- 此时,用于加速前端页面开发的 Web框架(MVC) 是关键。
- 分布式服务架构
- 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。
- 此时,用于提高业务复用及整合的 分布式服务框架(RPC) 是关键。
- 流动计算架构
- 当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。
- 此时,用于提高机器利用率的 资源调度和治理中心(SOA) 是关键。
本质:JBoss做的一个Jar包
目的:快速开发高性能、高可靠性的网络服务器和客户端程序
优点:提供异步的、事件驱动的网络应用程序框架和工具
通俗的说:一个好使的处理Socket的东东
如果没有Netty?
远古:java.net + java.io
近代:java.nio
其他:Mina,Grizzly
为什么不是Mina?
1、都是Trustin Lee的作品,Netty更晚;
2、Mina将内核和一些特性的联系过于紧密,使得用户在不需要这些特性的时候无法脱离,相比下性能会有所下降,Netty解决了这个设计问题;
3、Netty的文档更清晰,很多Mina的特性在Netty里都有;
4、Netty更新周期更短,新版本的发布比较快;
5、它们的架构差别不大,Mina靠apache生存,而Netty靠jboss,和jboss的结合度非常高,Netty有对google protocal buf的支持,有更完整的ioc容器支持(spring,guice,jbossmc和osgi);
6、Netty比Mina使用起来更简单,Netty里你可以自定义的处理upstream events 或/和 downstream events,可以使用decoder和encoder来解码和编码发送内容;
7、Netty和Mina在处理UDP时有一些不同,Netty将UDP无连接的特性暴露出来;而Mina对UDP进行了高级层次的抽象,可以把UDP当成"面向连接"的协议,而要Netty做到这一点比较困难。
Netty的特性
设计
统一的API,适用于不同的协议(阻塞和非阻塞)
基于灵活、可扩展的事件驱动模型
高度可定制的线程模型
可靠的无连接数据Socket支持(UDP)
性能
更好的吞吐量,低延迟
更省资源
尽量减少不必要的内存拷贝
安全
完整的SSL/TLS和STARTTLS的支持
能在Applet与Android的限制环境运行良好
健壮性
不再因过快、过慢或超负载连接导致OutOfMemoryError
不再有在高速网络环境下NIO读写频率不一致的问题
易用
完善的JavaDoc,用户指南和样例
简洁简单
仅信赖于JDK1.5
看例子吧!
Server端:
Java代码

- package me.hello.netty;
-
- import org.jboss.netty.bootstrap.ServerBootstrap;
- import org.jboss.netty.channel.*;
- import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
- import org.jboss.netty.handler.codec.string.StringDecoder;
- import org.jboss.netty.handler.codec.string.StringEncoder;
-
- import java.net.InetSocketAddress;
- import java.util.concurrent.Executors;
-
- /**
- * God Bless You!
- * Author: Fangniude
- * Date: 2013-07-15
- */
- public class NettyServer {
- public static void main(String[] args) {
- ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
-
- // Set up the default event pipeline.
- bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
- @Override
- public ChannelPipeline getPipeline() throws Exception {
- return Channels.pipeline(new StringDecoder(), new StringEncoder(), new ServerHandler());
- }
- });
-
- // Bind and start to accept incoming connections.
- Channel bind = bootstrap.bind(new InetSocketAddress(8000));
- System.out.println("Server已经启动,监听端口: " + bind.getLocalAddress() + ", 等待客户端注册。。。");
- }
-
- private static class ServerHandler extends SimpleChannelHandler {
- @Override
- public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
- if (e.getMessage() instanceof String) {
- String message = (String) e.getMessage();
- System.out.println("Client发来:" + message);
-
- e.getChannel().write("Server已收到刚发送的:" + message);
-
- System.out.println("\n等待客户端输入。。。");
- }
-
- super.messageReceived(ctx, e);
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
- super.exceptionCaught(ctx, e);
- }
-
- @Override
- public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
- System.out.println("有一个客户端注册上来了。。。");
- System.out.println("Client:" + e.getChannel().getRemoteAddress());
- System.out.println("Server:" + e.getChannel().getLocalAddress());
- System.out.println("\n等待客户端输入。。。");
- super.channelConnected(ctx, e);
- }
- }
- }
客户端:
Java代码

- package me.hello.netty;
-
- import org.jboss.netty.bootstrap.ClientBootstrap;
- import org.jboss.netty.channel.*;
- import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
- import org.jboss.netty.handler.codec.string.StringDecoder;
- import org.jboss.netty.handler.codec.string.StringEncoder;
-
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
- import java.net.InetSocketAddress;
- import java.util.concurrent.Executors;
-
- /**
- * God Bless You!
- * Author: Fangniude
- * Date: 2013-07-15
- */
- public class NettyClient {
-
- public static void main(String[] args) {
- // Configure the client.
- ClientBootstrap bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
-
- // Set up the default event pipeline.
- bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
- @Override
- public ChannelPipeline getPipeline() throws Exception {
- return Channels.pipeline(new StringDecoder(), new StringEncoder(), new ClientHandler());
- }
- });
-
- // Start the connection attempt.
- ChannelFuture future = bootstrap.connect(new InetSocketAddress("localhost", 8000));
-
- // Wait until the connection is closed or the connection attempt fails.
- future.getChannel().getCloseFuture().awaitUninterruptibly();
-
- // Shut down thread pools to exit.
- bootstrap.releaseExternalResources();
- }
-
- private static class ClientHandler extends SimpleChannelHandler {
- private BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));
-
- @Override
- public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
- if (e.getMessage() instanceof String) {
- String message = (String) e.getMessage();
- System.out.println(message);
-
- e.getChannel().write(sin.readLine());
-
- System.out.println("\n等待客户端输入。。。");
- }
-
- super.messageReceived(ctx, e);
- }
-
- @Override
- public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
- System.out.println("已经与Server建立连接。。。。");
- System.out.println("\n请输入要发送的信息:");
- super.channelConnected(ctx, e);
-
- e.getChannel().write(sin.readLine());
- }
- }
- }
Netty整体架构

Netty组件
ChannelFactory
Boss
Worker
Channel
ChannelEvent
Pipeline
ChannelContext
Handler
Sink
Server端核心类
NioServerSocketChannelFactory
NioServerBossPool
NioWorkerPool
NioServerBoss
NioWorker
NioServerSocketChannel
NioAcceptedSocketChannel
DefaultChannelPipeline
NioServerSocketPipelineSink
Channels
ChannelFactory
Channel工厂,很重要的类
保存启动的相关参数
NioServerSocketChannelFactory
NioClientSocketChannelFactory
NioDatagramChannelFactory
这是Nio的,还有Oio和Local的
SelectorPool
Selector的线程池
NioServerBossPool 默认线程数:1
NioClientBossPool 1
NioWorkerPool 2 * Processor
NioDatagramWorkerPool
Selector
选择器,很核心的组件
NioServerBoss
NioClientBoss
NioWorker
NioDatagramWorker
Channel
通道
NioServerSocketChannel
NioClientSocketChannel
NioAcceptedSocketChannel
NioDatagramChannel
Sink
负责和底层的交互
如bind,Write,Close等
NioServerSocketPipelineSink
NioClientSocketPipelineSink
NioDatagramPipelineSink
Pipeline
负责维护所有的Handler
ChannelContext
一个Channel一个,是Handler和Pipeline的中间件
Handler
对Channel事件的处理器
ChannelPipeline


优秀的设计----事件驱动

优秀的设计----线程模型

注意事项
解码时的Position
Channel的关闭
更多Handler
Channel的关闭
用完的Channel,可以直接关闭;
1、ChannelFuture加Listener
2、writeComplete
一段时间没用,也可以关闭
TimeoutHandler