poll

Netty性能优化

瘦欲@ 提交于 2019-11-26 13:55:57
1.Netty为Linux提供了一组NIO API,其以一种和它本身的设计更加一致的方式使用epoll,并 且以一种更加轻量的方式使用中断。如果你的应用程序旨在运行于Linux系统,那么请考虑利用 这个版本的传输;你将发现在高负载下它的性能要优于JDK的NIO实现。如果要在那个代码清单中使用epoll 替代NIO,只需要将NioEventLoopGroup替换为EpollEventLoopGroup , 并且将NioServerSocketChannel.class 替换为EpollServerSocketChannel.class 即可。 2.ChannelHandler处理器,如果是无状态的,能使用单例就使用单例。减少对象开销,提高高并发。 3.耗时的网络请求,数据库操作,业务处理请使用业务线程池处理。另外注意writeAndFlush()是异步方法,如果想监控写事件是否完成,可以添加监听器。 4.序列化和反序列化,可以考虑使用Protobuf二进制流,提高传输速率 5.可以自定义实现编解码 6.复杂IM应用应该使用长连接和短链接相互配合,某些业务场景也可以使用UDP协议来实现 来源: https://blog.csdn.net/zhulinfeng2012/article/details/98882589

Epoll的使用例子

时光怂恿深爱的人放手 提交于 2019-11-26 11:16:23
本篇文章在上一篇的基础上,使用 epoll 实现了一个事件监听和回调处理的模块。如何编写一个使用该模块的例子呢? 监测什么类型的fd,监测什么类型的事件,监测到事件以后需要做什么?后来可以看看如何将该模块与socket , 回调函数, 线程池联系起来。 #include<sys/epoll.h> // epoll_create, epoll_ctl, epoll_wait #include <mutex> // std::mutex #include <functional> // std::function #include <iostream> #include <memory> // std::unique_ptr #include <unistd.h> // close class Epoll{ public: class ActiveEvents { public: ActiveEvents( int num, const struct epoll_event* events): num_( num ), events_( events ) { } int num() const { return num_; } const struct epoll_event* events() const { return events_; } private: int num_;

Socket封装之聊天程序(一)

﹥>﹥吖頭↗ 提交于 2019-11-26 04:27:39
  之前使用IPC编写过聊天程序,但是这样仅能在同一台计算机上进行聊天;要使得在不同的计算机(不同的IP+端口)上也能进行通信,就需要用到socket编程。前面说到,要处理多客户端的响应问题,需要I/O复用,即调用select或者epoll。通常我们使用epoll函数,以下例子也是。   接下来,我们需要封装一个地址类。为什么要封装这样一个类呢?   在前面的练习中,我们可以看到,在socket规程中,需要反复用到struct sockaddr_in 这个地址,包括以下的bind绑定过程也是经常出现的,而且这些方法其实都是系统函数,我们并不希望每次都直接使用,不进繁琐难记,而且可读性差。所以,我们需要封装一个地址类CAdress,将这些步骤在函数内部实现。       编写CAdress类    CAdress.h: #ifndef _ADRESS_H_ #define _ADRESS_H_ #include <netinet/in.h> //sockaddr_in #include <arpa/inet.h> class CAdress { public: CAdress(char *ip,unsigned short port); CAdress(); ~CAdress(); void setIP(char *ip); void setPort(unsigned short

Socket封装之聊天程序(二)

▼魔方 西西 提交于 2019-11-26 03:57:55
  今天,学习一下socket的封装。 类图   首先,我们把需要封装的各个类初步的设计如下:   接下来,我们建立类与类之间的关系:   其中,CStream类可有可无,这个类是用来封装各种读写流的。 socket封装 stream类 stream.h: class CStream { public: CStream(int fd = -1); ~CStream(); void SetFd(int fd); int GetFd(); int Read(char *buf, int count); //阻塞读 int Read(char *buf, int count, int sec); //超时读 // int Read(char *buf, int count, CAddress &addr); //UDP读 bool Write(char *buf,int count); //普通写 private: int m_fd; }; stream.cpp: include "stream.h" CStream::CStream( int fd /*= -1*/ ) { this->m_fd = fd; } CStream::~CStream() { } void CStream::SetFd( int fd ) { this->m_fd = fd; } int CStream:

Socket封装之聊天程序(三)

故事扮演 提交于 2019-11-26 03:57:52
  今天,完成一下epoll的封装。 类图   首先,还是画下类图,初步设计一下。   具体函数,我们下面详解。 epoll封装 EpollBase类 CEpollBase.h: class CEpollBase { public: CEpollBase(int max_events); virtual ~CEpollBase(); bool Create(int size); bool AddEvent(int fd,int events); bool ModEvent(int fd,int events); bool DelEvent(int fd,int events); bool Wait(int timeout = -1); //监听一次事件的发生 virtual void onEvent() = 0; void Start(); void Stop(); protected: struct epoll_event *m_rlt_events; struct epoll_event m_event; int m_nEvent; int m_epfd; private: int m_max_events; bool isRun; };   在之前,我们监听事件的发生并进行处理,是放在while(1)循环里的,但是,真正项目里是不能存在死循环的,所以,这里的Wait(

modbus_tk与Modubs Slave结合使用

百般思念 提交于 2019-11-26 03:38:28
下载两个软件: Modbus Slave/Poll Modbus Slave(用来模拟客户端(从))和Modbus Poll(用来模拟服务端(主)) Modbus Poll是非常流行的Modbus Master模拟器,用于测试和调试从设备。支持Modbus RTU/ASCII和Modbus TCP/IP。 一、模拟器的使用 1.1 配置Modbus Poll 配置Modbus Poll的连接 配置Modbus Poll的参数 参数说明 Tx:向主站发送数据帧的次数 Err:通讯错误次数 ID:模拟Modbus子设备的设备地址 F:使用的Modbus功能码 SR:扫描周期 Slave ID:Modbus从站地址 Function:寄存器的功能码 Address:寄存器起始地址,默认从0开始 Quantity:寄存器连续个数,默认为10个 Scan Rate:读取数据的周期,单位毫秒,默认1000ms 寄存器功能码 代码 中文名称 寄存器PLC地址 位操作/字操作 操作数量 01 读线圈状态 00001-09999 位操作 单个或多个 02 读离散输入状态 10001-19999 位操作 单个或多个 03 读保持寄存器 40001-49999 字操作 单个或多个 04 读输入寄存器 30001-39999 字操作 单个或多个 05 写单个线圈 00001-09999 位操作 单个 06

阻塞队列 BlockingQueue 常用方法详解

不羁的心 提交于 2019-11-26 02:38:29
1、offer()和add()的区别 add()和offer()都是向队列中添加一个元素。但是如果想在一个满的队列中加入一个新元素,调用 add() 方法就会抛出一个 unchecked 异常,而调用 offer() 方法会返回 false。可以据此在程序中进行有效的判断! 2、peek()和element()的区别 peek()和element()都将在不移除的情况下返回队头,但是peek()方法在队列为空时返回null,调用element()方法会抛出NoSuchElementException异常。 3、poll()和remove()的区别 poll()和remove()都将移除并且返回队头,但是在poll()在队列为空时返回null,而remove()会抛出NoSuchElementException异常。 1、offer()和add()的区别 add()和offer()都是向队列中添加一个元素。但是如果想在一个满的队列中加入一个新元素,调用 add() 方法就会抛出一个 unchecked 异常,而调用 offer() 方法会返回 false。可以据此在程序中进行有效的判断! 2、peek()和element()的区别 peek()和element()都将在不移除的情况下返回队头,但是peek()方法在队列为空时返回null,调用element(

Kafka整合Spring——消费者端

妖精的绣舞 提交于 2019-11-25 23:09:53
Kafka消费者端 可靠性保证 作为消费端,消费数据需要考虑的是: 1、不重复消费消息 2、不缺失消费消息 分区分配策略 一个 consumer group 中有多个 consumer,一个 topic 有多个 partition,所以必然会涉及到 partition 的分配问题,即确定那个 partition 由哪个 consumer 来消费。 Kafka 有两种分配策略,一是 RoundRobin(轮询调度算法(Round-Robin Scheduling)),一是 Range。 https://blog.csdn.net/u013256816/article/details/81123600 朱小厮的博客(《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》作者) offset 消费者端的可靠性需要依靠offect来进行保证,这里的offset不是broker的offect,而是consumer的消费位移偏移量,它在broker中被维护。由于 consumer 在消费过程中可能会出现断电宕机等故障, consumer 恢复后,需要从故 障前的位置的继续消费,所以 consumer 需要实时记录自己消费到了哪个 offset,以便故障恢复后继续消费。 Kafka 0.9 版本之前, consumer 默认将 offset 保存在 Zookeeper 中,从

【IO多路复用】 -- 2019-08-07 10:55:51

天涯浪子 提交于 2019-11-25 20:15:21
原创: http://106.13.73.98/__/8/ 目录 一、IO模型介绍 二、阻塞IO(blocking IO) 三、非阻塞IO(non-blocking IO) 四、多路复用IO(IO multiplexing) 五、异步IO(Asynchronous I/O) 六、模型比较分析 七、关于select、poll、epoll 一、IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下: 同步、异步、阻塞、非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出的答案都可能不同,比如wiki,就认为asynchronous IO和non-blocking IO是一个东西。这其实是因为不同的人的知识背景不同,并且在讨论这个问题的时候上下文(context)也不相同。所以,为了更好的回答这个问题,我先限定一下本文的上下文。 本文讨论的背景是Linux环境下的network IO。本文最重要的参考文献是Richard Stevens的“UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking ”,6.2节“I/O Models ”