RPC 设计与实现
互联网架构演变(微观)
- 单一架构,以实现功能为目的,扩展性差 - 数据访问层问题
- 垂直架构,业务拆分,各司其职 - 控制层
M
|V
解耦 - 分布式服务,服务间的相互调度 - RPC
remote process call
- 流动式计算,伸缩性,扩展性 - SOA治理
高并发互联网架构设计(宏观)
X轴
:水平扩展,应用具有可复制性木桶原理
Y轴
:垂直拆分各司其职
泳道设计
Z轴
:将X/Y打包,做物理隔离
RPC 系统间通讯实现手段
- 即时消息-点对点 消息发送和接收方必须同时在线
WebService-SOAP
tcp/ip数据传输层 - 离线消息- 异步消息 不要求消息发送方和接收方同时在线
email
MQ
TCP/IP通讯 | UDP- 网络编程
-
IO 非常重要
BIO
/NIO
-
BIO
- FileInputStream、FileOutputStream
字节流
- BufferedReader/BufferedWriter
字符流
- InputStreamReader、OutputStreamWriter
桥转换
- PrintStream、PrintWriter
- ObjectInputStream|ObjectOutputStream
序列化
- FileInputStream、FileOutputStream
-
NIO
- FileChannel
- ByteBuffer
读
:磁盘 --> FileChannel#read–>ByteBuffer(变量)写
:ByteBuffer(变量)–>FileChannel#write–>磁盘只读FileChanel
: FileInputStream#getChannel();可写FileChanel
: FileOutputStream#getChannel();ByteBuffer常见操作
FileChannel inFileChannel=new FileInputStream("C:\\Users\\Administrator\\Desktop\\FeiQ2013.exe").getChannel(); FileChannel outFileChannel=new FileOutputStream("C:\\Users\\Administrator\\Desktop\\FeiQ2018.exe").getChannel(); //创建ByteBuffer ByteBuffer buffer=ByteBuffer.allocate(1024); while(true){ buffer.clear(); int n = inFileChannel.read(buffer); if(n==-1) break; buffer.flip(); outFileChannel.write(buffer); } inFileChannel.close(); outFileChannel.close();
-
-
网络
BIO网络编程
、NIO网络编程
-
BIO
- ServerSocket
服务端
- Socket
客户端
- ServerSocket
-
NIO
- ServerSocketChannel
服务端
- SocketChannel
客户端
- Selector
通道选择器
- ServerSocketChannel
-
//1.创建ServerSocket
ServerSocket ss=new ServerSocket();
//2.绑定监听端口
ss.bind(new InetSocketAddress(9999));
//3.等待请求到来 转发新的Socket
System.out.println("我在9999等待...");
Socket socket = ss.accept();
//4.获取意图
InputStream is = socket.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
StringBuilder sb=new StringBuilder();
String line=null;
while ((line=br.readLine())!=null){
sb.append(line);
}
System.out.println("服务器收到:"+sb.toString());
//4.给出响应
OutputStream os = socket.getOutputStream();
PrintWriter pw=new PrintWriter(os);
pw.println(new Date().toLocaleString());
pw.flush();
//5.告知客户端写结束
socket.shutdownOutput();
//6.释放socket资源
socket.close();
BIO编程诟病
:多线程模型解决服务端并发,但是无法判断当前处理的IO状态是否就绪,此时就会导致线程在做无畏等待,导致系统资源利用率不高。先开线程 -> 在线程等待IO就绪->处理IO->线程资源释放
NIO
//1.创建ServerSocket
ServerSocketChannel ssc= ServerSocketChannel.open();
//2.绑定监听端口
ssc.bind(new InetSocketAddress(9999));
//3.设置通道非阻塞
ssc.configureBlocking(false);
//4.创建Selector 通道选择器
Selector selector= Selector.open();
//5.注册通道事件
ssc.register(selector, SelectionKey.OP_ACCEPT);
while(true){
System.out.println("选择keys中...");
//可以出来keys的数目,如果没有该方法block
int n = selector.select();
if(n>0){
Iterator<SelectionKey> iterator =selector.selectedKeys().iterator();
while (iterator.hasNext()){
SelectionKey key = iterator.next();
//处理事件key
if(key.isAcceptable()){
System.out.println("accept...");
ServerSocketChannel serverSocketChannel= (ServerSocketChannel) key.channel();
SocketChannel sc = serverSocketChannel.accept();
//设置非阻塞
sc.configureBlocking(false);
sc.register(selector,SelectionKey.OP_READ);
}else if(key.isReadable()){
System.out.println("read...");
SocketChannel sc =(SocketChannel) key.channel();
ByteArrayOutputStream baos=new ByteArrayOutputStream();
ByteBuffer buffer=ByteBuffer.allocate(1024);
while (true){
buffer.clear();
int num = sc.read(buffer);
if(num==-1) break;
buffer.flip();
baos.write(buffer.array(),0,num);
}
//注册写
sc.register(selector,SelectionKey.OP_WRITE,baos);
}else if(key.isWritable()){
System.out.println("write...");
SocketChannel sc =(SocketChannel) key.channel();
ByteBuffer byteBuffer=ByteBuffer.wrap((new Date().toString()).getBytes());
sc.write(byteBuffer);
sc.shutdownOutput();
sc.close();
}
//移除事件
iterator.remove();
}
下一篇:Netty的基础使用以及原理(NIO框架)
下一篇:自定义RPC设计与实现