返回首页
苏宁会员
购物车 0
易付宝
手机苏宁

服务体验

店铺评分与同行业相比

用户评价:----

物流时效:----

售后服务:----

  • 服务承诺: 正品保障
  • 公司名称:
  • 所 在 地:
本店所有商品

  • [正版]Linux多线程服务端编程 使用muduo C++网络库 陈硕 linux程序设计书 编程模型使用方法 Lin
  • 正版图书!品质保证!默认发最新版本!收藏店铺可享优先发货!
    • 作者: 无著
    • 出版社: 电子工业出版社
    • 出版时间:1
    送至
  • 由""直接销售和发货,并提供售后服务
  • 加入购物车 购买电子书
    服务

    看了又看

    商品预定流程:

    查看大图
    /
    ×

    苏宁商家

    商家:
    友一个文化制品专营店
    联系:
    • 商品

    • 服务

    • 物流

    搜索店内商品

    商品分类

    商品参数
    • 作者: 无著
    • 出版社:电子工业出版社
    • 出版时间:1
    • ISBN:9782642325488
    • 版权提供:电子工业出版社

            铺公告

      为保障消费者合理购买需求及公平交易机会,避免因非生活消费目的的购买货囤积商品,抬价转售等违法行为发生,店铺有权对异常订单不发货且不进行赔付。异常订单:包括但不限于相同用户ID批量下单,同一用户(指不同用户ID,存在相同/临近/虚构收货地址,或相同联系号码,收件人,同账户付款人等情形的)批量下单(一次性大于5本),以及其他非消费目的的交易订单。

    温馨提示:请务必当着快递员面开箱验货,如发现破损,请立即拍照拒收,如验货有问题请及时联系在线客服处理,(如开箱验货时发现破损,所产生运费由我司承担,一经签收即为货物完好,如果您未开箱验货,一切损失就需要由买家承担,所以请买家一定要仔细验货)。

      关于退货运费:对于下单后且物流已发货货品在途的状态下,原则上均不接受退货申请,如顾客原因退货需要承担来回运费,如因产品质量问题(非破损问题)可在签收后,联系在线客服。

     

     

       
     
     
     
         
     
     
       
     
     
     
     
       
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
       
     
     
     
         
     
     
       
     
     
       
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
       
     
     
     
         
     
     
       
     
     
     
       
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
       
     
     
     
         
     
     
       
     
     
     
     
     
     
     

    产品展示
    基本信息
    图书名称:
     Linux多线程服务端编程 使用muduo C++网络库   
    作 者:
     陈硕   
    定价:
     128.00
    ISBN号:
     9787121192821
    出版社:
     电子工业出版社
    开本:
     16
    装帧:
     平装
    出版日期:
     2013-01-01
    印刷日期:
     2013-01-01
    编辑推荐
    多年编写生产环境下多线程服务端程序经验之精华,示范在多核时代采用现代C++编写多线程TCP网络服务器的正规做法
    内容介绍
    《Linux多线程服务端编程 使用muduoC++网络库》主要讲述采用现代C++在x86-64Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即oneloopperthread。这是在Linux下以native语言编写用户态高性能网络程序成熟的模式,掌握之后可顺利地开发各类常见的服务端网络应用程序。本书以muduo网络库为例,讲解这种编程模型的使用方法及注意事项。
    《Linux多线程服务端编程 使用muduoC++网络库》的宗旨是贵精不贵多。掌握两种基本的同步原语就可以满足各种多线程同步的功能需求,还能写出更易用的同步设施。掌握一种进程间通信方式和一种多线程网络编程模型就足以应对日常开发任务,编写运行于公司内网环境的分布式服务系统。
    作者介绍
    陈硕,北京师范大学硕士,擅长C++ 多线程网络编程和实时分布式系统架构。曾在摩根士丹利IT 部门工作5 年,从事实时外汇交易系统开发。现在在美国加州硅谷某互联网大公司工作,从事大规模分布式系统的可靠性工程。编写了开源C++ 网络库muduo,参与翻译了《代码大Q(第2 版)》和《C++ 编程规范(繁体版)》,整理了《C++ Primer (第4 版)(评注版)》,并曾多次在各地技术大会演讲。
    目录
    第1 部分 C++ 多线程系统编程
    第1 章 线程AQ的对象生命期管理
    1.1 当析构函数遇到多线程
    1.1.1 线程AQ的定义
    1.1.2 MutexLock 与MutexLockGuard
    1.1.3 一个线程AQ的Counter 示例
    1.2 对象的创建很简单.
    1.3 销毁太难
    1.3.1 mutex 不是办法
    1.3.2 作为数据成员的mutex 不能保护析构.
    1.4 线程AQ的Observer 有多难.
    1.5 原始指针有何不妥.
    1.6 神器shared_ptr/weak_ptr
    1.7 插曲:系统地避免各种指针错误.
    1.8 应用到Observer 上
    1.9 再论shared_ptr 的线程AQ.
    1.10 shared_ptr 技术与陷阱
    1.11 对象池.
    1.11.1 enable_shared_from_this
    1.11.2 弱回调.
    1.12 替代方案
    1.13 心得与小结.
    1.14 Observer 之谬.
    第2 章 线程同步精要
    2.1 互斥器(mutex) .
    2.1.1 只使用非递归的mutex
    2.1.2 死锁
    2.2 条件变量(condition variable) .
    2.3 不要用读写锁和信号量
    2.4 封装MutexLock、MutexLockGuard、Condition
    2.5 线程AQ的Singleton 实现
    2.6 sleep(3) 不是同步原语
    2.7 归纳与总结.
    2.8 借shared_ptr 实现copy-on-write
    第3 章 多线程服务器的适用场合与常用编程模型
    3.1 进程与线程.
    3.2 单线程服务器的常用编程模型
    3.3 多线程服务器的常用编程模型
    3.3.1 one loop per thread
    3.3.2 线程池.
    3.3.3 推荐模式
    3.4 进程间通信只用TCP .
    3.5 多线程服务器的适用场合.
    3.5.1 B须用单线程的场合.
    3.5.2 单线程程序的优缺点.
    3.5.3 适用多线程程序的场景
    3.6 “多线程服务器的适用场合”例释与答疑
    第4 章 C++ 多线程系统编程精要
    4.1 基本线程原语的选用.
    4.2 C/C++ 系统库的线程AQ性.
    4.3 Linux 上的线程标识
    4.4 线程的创建与销毁的守则.
    4.4.1 pthread_cancel 与C++ .
    4.4.2 exit(3) 在C++ 中不是线程AQ的.
    4.5 善用__thread 关键字.
    4.6 多线程与IO
    4.7 用RAII 包装文件描述符.
    4.8 RAII 与fork() .
    4.9 多线程与fork() .
    4.10 多线程与signal
    4.11 Linux 新增系统调用的启示
    第5 章 GX的多线程日志
    5.1 功能需求
    5.2 性能需求
    5.3 多线程异步日志
    5.4 其他方案

    第2 部分 muduo 网络库
    第6 章 muduo 网络库简介
    6.1 由来.
    6.2 安装.
    6.3 目录结构
    6.3.1 代码结构
    6.3.2 例子
    6.3.3 线程模型
    6.4 使用教程
    6.4.1 TCP 网络编程本质论.
    6.4.2 echo 服务的实现.
    6.4.3 七步实现finger 服务.
    6.5 性能评测
    6.5.1 muduo 与Boost.Asio、libevent2 的吞吐量对比
    6.5.2 击鼓传花:对比muduo 与libevent2 的事件处理效率
    6.5.3 muduo 与Nginx 的吞吐量对比.
    6.5.4 muduo 与ZeroMQ 的延迟对比.
    6.6 详解muduo 多线程模型.
    6.6.1 数独求解服务器
    6.6.2 常见的并发网络服务程序设计方案.
    第7 章 muduo 编程示例
    7.1 五个简单TCP 示例
    7.2 文件传输
    7.3 Boost.Asio 的聊天服务器.
    7.3.1 TCP 分包
    7.3.2 消息格式
    7.3.3 编解码器LengthHeaderCodec
    7.3.4 服务端的实现.
    7.3.5 客户端的实现.
    7.4 muduo Buffer 类的设计与使用.
    7.4.1 muduo 的IO 模型
    7.4.2 为什么non-blocking 网络编程中应用层buffer 是B需的
    7.4.3 Buffer 的功能需求
    7.4.4 Buffer 的数据结构
    7.4.5 Buffer 的操作.
    7.4.6 其他设计方案.
    7.4.7 性能是不是问题
    7.5 一种自动反射消息类型的Google Protobuf 网络传输方案
    7.5.1 网络编程中使用Protobuf 的两个先决条件.
    7.5.2 根据type name 反射自动创建Message 对象
    7.5.3 Protobuf 传输格式
    7.6 在muduo 中实现Protobuf 编解码器与消息分发器
    7.6.1 什么是编解码器(codec)
    7.6.2 实现ProtobufCodec .
    7.6.3 消息分发器(dispatcher)有什么用
    7.6.4 ProtobufCodec 与ProtobufDispatcher 的综合运用.
    7.6.5 ProtobufDispatcher 的两种实现
    7.6.6 ProtobufCodec 和ProtobufDispatcher 有何意义.
    7.7 限制服务器的ZD并发连接数
    7.7.1 为什么要限制并发连接数
    7.7.2 在muduo 中限制并发连接数
    7.8 定时器.
    7.8.1 程序中的时间.
    7.8.2 Linux 时间函数
    7.8.3 muduo 的定时器接口.
    7.8.4 Boost.Asio Timer 示例
    7.8.5 Java Netty 示例
    7.9 测量两台机器的网络延迟和时间差.
    7.10 用timing wheel 踢掉空闲连接
    7.10.1 timing wheel 原理
    7.10.2 代码实现与改进
    7.11 简单的消息广播服务.
    7.12 “串并转换”连接服务器及其自动化测试
    7.13 socks4a 代理服务器
    7.13.1 TCP 中继器
    7.13.2 socks4a 代理服务器
    7.13.3 N : 1 与1 : N 连接转发
    7.14 短址服务
    7.15 与其他库集成.
    7.15.1 UDNS .
    7.15.2 c-ares DNS .
    7.15.3 curl .
    7.15.4 更多
    第8 章 muduo 网络库设计与实现
    8.0 什么都不做的EventLoop .
    8.1 Reactor 的关键结构
    8.1.1 Channel class .
    8.1.2 Poller class
    8.1.3 EventLoop 的改动.
    8.2 TimerQueue 定时器
    8.2.1 TimerQueue class .
    8.2.2 EventLoop 的改动.
    8.3 EventLoop::runInLoop() 函数
    8.3.1 提高TimerQueue 的线程AQ性.
    8.3.2 EventLoopThread class
    8.4 实现TCP 网络库
    8.5 TcpServer 接受新连接
    8.5.1 TcpServer class
    8.5.2 TcpConnection class .
    8.6 TcpConnection 断开连接.
    8.7 Buffer 读取数据
    8.7.1 TcpConnection 使用Buffer 作为输入缓冲.
    8.7.2 Buffer::readFd()
    8.8 TcpConnection 发送数据.
    8.9 完善TcpConnection
    8.9.1 SIGPIPE
    8.9.2 TCP No Delay 和TCP keepalive
    8.9.3 WriteCompleteCallback 和HighWaterMarkCallback .
    8.10 多线程TcpServer .
    8.11 Connector .
    8.12 TcpClient .
    8.13 epoll
    8.14 测试程序一览.

    第3 部分 工程实践经验谈
    第9 章 分布式系统工程实践
    9.1 我们在技术浪潮中的位置.
    9.1.1 分布式系统的本质困难
    9.1.2 分布式系统是个险恶的问题.
    9.2 分布式系统的可靠性浅说.
    9.2.1 分布式系统的软件不要求7 24 可靠
    9.2.2 “能随时重启进程”作为程序设计目标.
    9.3 分布式系统中心跳协议的设计
    9.4 分布式系统中的进程标识.
    9.4.1 错误做法
    9.4.2 正确做法
    9.4.3 TCP 协议的启示
    9.5 构建易于维护的分布式程序.
    9.6 为系统演化做准备.
    9.6.1 可扩展的消息格式
    9.6.2 反面教材:ICE 的消息打包格式.
    9.7 分布式程序的自动化回归测试
    9.7.1 单元测试的能与不能.
    9.7.2 分布式系统测试的要点
    9.7.3 分布式系统的抽象观点
    9.7.4 一种自动化的回归测试方案.
    9.7.5 其他用处
    9.8 分布式系统部署、监控与进程管理的几重境界.
    9.8.1 境界1:Q手工操作.
    9.8.2 境界2:使用零散的自动化脚本和第三方组件.
    9.8.3 境界3:自制机群管理系统,集中化配置.
    9.8.4 境界4:机群管理与naming service 结合.
    第10 章 C++ 编译链接模型精要
    10.1 C 语言的编译模型及其成因.
    10.1.1 为什么C 语言需要预处理
    10.1.2 C 语言的编译模型.
    10.2 C++ 的编译模型
    10.2.1 单遍编译
    10.2.2 前向声明
    10.3 C++ 链接(linking) .
    10.3.1 函数重载
    10.3.2 inline 函数.
    10.3.3 模板
    10.3.4 虚函数.
    10.4 工程项目中头文件的使用规则
    10.4.1 头文件的害处.
    10.4.2 头文件的使用规则
    10.5 工程项目中库文件的组织原则
    10.5.1 动态库是有害的
    10.5.2 静态库也好不到哪儿去
    10.5.3 源码编译是王道
    第11 章 反思C++ 面向对象与虚函数
    11.1 朴实的C++ 设计
    11.2 程序库的二进制兼容性
    11.2.1 什么是二进制兼容性.
    11.2.2 有哪些情况会破坏库的ABI .
    11.2.3 哪些做法多半是AQ的
    11.2.4 反面教材:COM .
    11.2.5 解决办法
    11.3 避免使用虚函数作为库的接口
    11.3.1 C++ 程序库的作者的生存环境
    11.3.2 虚函数作为库的接口的两大用途
    11.3.3 虚函数作为接口的弊端
    11.3.4 假如Linux 系统调用以COM 接口方式实现
    11.3.5 Java 是如何应对的
    11.4 动态库接口的推荐做法
    11.5 以boost::function 和boost::bind 取代虚函数.
    11.5.1 基本用途
    11.5.2 对程序库的影响
    11.5.3 对面向对象程序设计的影响.
    11.6 iostream 的用途与局限
    11.6.1 stdio 格式化输入输出的缺点.
    11.6.2 iostream 的设计初衷.
    11.6.3 iostream 与标准库其他组件的交互.
    11.6.4 iostream 在使用方面的缺点.
    11.6.5 iostream 在设计方面的缺点.
    11.6.6 一个300 行的memory buffer output stream .
    11.6.7 现实的C++ 程序如何做文件IO .
    11.7 值语义与数据抽象.
    11.7.1 什么是值语义.
    11.7.2 值语义与生命期
    11.7.3 值语义与标准库
    11.7.4 值语义与C++ 语言
    11.7.5 什么是数据抽象
    11.7.6 数据抽象所需的语言设施
    11.7.7 数据抽象的例子
    第12 章 C++ 经验谈
    12.1 用异或来交换变量是错误的.
    12.1.1 编译器会分别生成什么代码.
    12.1.2 为什么短的代码不一定快
    12.2 不要重载Q局::operator new()
    12.2.1 内存管理的基本要求.
    12.2.2 重载::operator new() 的理由.
    12.2.3 ::operator new() 的两种重载方式.
    12.2.4 现实的开发环境
    12.2.5 重载::operator new() 的困境.
    12.2.6 解决办法:替换malloc()
    12.2.7 为单独的class 重载::operator new() 有问题吗.
    12.2.8 有B要自行定制内存分配器吗
    12.3 带符号整数的除法与余数.
    12.3.1 语言标准怎么说
    12.3.2 C/C++ 编译器的表现.
    12.3.3 其他语言的规定
    12.3.4 脚本语言解释器代码.
    12.3.5 硬件实现
    12.4 在单元测试中mock 系统调用
    12.4.1 系统函数的依赖注入.
    12.4.2 链接期垫片(link seam)
    12.5 慎用匿名namespace .
    12.5.1 C 语言的static 关键字的两种用法.
    12.5.2 C++ 语言的static 关键字的四种用法
    12.5.3 匿名namespace 的不利之处.
    12.5.4 替代办法
    12.6 采用有利于版本管理的代码格式.
    12.6.1 对diff 友好的代码格式
    12.6.2 对grep 友好的代码风格.
    12.6.3 一切为了效率.
    12.7 再探std::string .
    12.7.1 直接拷贝(eager copy) .
    12.7.2 写时复制(copy-on-write) .
    12.7.3 短字符串优化(SSO)
    12.8 用STL algorithm 轻松解决几道算法面试题
    12.8.1 用next_permutation() 生成排列与组合
    12.8.2 用unique() 去除连续重复空白.
    12.8.3 用{make,push,pop}_heap() 实现多路归并
    12.8.4 用partition() 实现“重排数组,让奇数位于偶数前面”
    12.8.5 用lower_bound() 查找IP 地址所属的城市.

    第4 部分 附录
    附录A 谈一谈网络编程学习经验
    附录B 从《C++ Primer(第4 版)》入手学习C++
    附录C 关于Boost 的看法
    附录D 关于TCP 并发连接的几个思考题与试验
    在线试读部分章节
    附录A
    谈一谈网络编程学习经验
    本文谈一谈我在学习网络编程方面的一些个人经验。“网络编程”这个术语的范围很广,本文指用Sockets API 开发基于TCP/IP 的网络应用程序,具体定义见§A.1.5 “网络编程的各种任务角色”。
    受限于本人的经历和经验,本附录的适应范围是:
    x86-64 Linux 服务端网络编程,直接或间接使用Sockets API。
    公司内网。不一定是局域网,但总体位于公司防火墙之内,环境可控。
    本文可能不适合:
    PC 客户端网络编程,程序运行在客户的PC 上,环境多变且不可控。
    Windows 网络编程。
    面向公网的服务程序。
    高性能网络服务器。
    本文分两个部分:
    1. 网络编程的一些“胡思乱想”,以自问自答的形式谈谈我对这一领域的认识。
    2. 几本B看的书,基本上还是W. Richard Stevents 的那几本。
    另外,本文没有特别说明时均暗指TCP 协议,“连接”是“TCP 连接”,“服务
    端”是“TCP 服务端”。
    A.1 网络编程的一些“胡思乱想”
    以下大致列出我对网络编程的一些想法,前后无关联。
    A.1.1 网络编程是什么
    网络编程是什么?是熟练使用Sockets API 吗?说实话,在实际项目里我只用过
    两次Sockets API,其他时候都是使用封装好的网络库。
    DY次是2005 年在学校做一个羽毛球赛场计分系统:我用C# 编写运行在PC上的软件,负责比分的显示;再用C# 写了运行在PDA 上的计分界面,记分员拿着PDA 记录比分;这两部分程序通过TCP 协议相互通信。这其实是个简单的分布式系统,体育馆有几片场地,每个场地都有一名拿PDA 的记分员,每个场地都有两台显示比分的PC (显示器是42 寸平板电视,放在场地的对角,这样两边看台的观众都能看到比分)。这两台PC 的功能不完Q一样,一台只负责显示当前比分,另一台还要负责与PDA 通信,并更新数据库里的比分信息。此外,还有一台PC 负责周期性地从数据库读出Q部7 片场地的比分,显示在体育馆墙上的大屏幕上。这台PC 上还运行着一个程序,负责生成比分数据的静态页面,通过FTP 上传发布到某门户网站的体育频道。系统中还有一个录入赛程(参赛队、运动员、出场顺序等)数据库的程序,运行在数据库服务器上。算下来整个系统有十来个程序,运行在二十多台设备(PC 和PDA)上,还要考虑可靠性,避免single point of failure。
    这是我DY次写实际项目中的网络程序,当时写下来的感觉是像写命令行与用户交互的程序:程序在命令行输出一句提示语,等待客户输入一句话,然后处理客户输入,再输出下一句提示语,如此循环。只不过这里的“客户”不是人,而是另一个程序。在建立好TCP 连接之后,双方的程序都是read/write 循环(为求简单,我用的是blocking 读写),直到有一方断开连接。
    第二次是2010 年编写mudu网络库,我再次拿起了Sockets API,写了一个基于Reactor 模式的C++ 网络库。写这个库的目的之一就是想让日常的网络编程从Sockets API 的琐碎细节中解脱出来,让程序员专注于业务逻辑,把时间用在刀刃上。mudu网络库的示例代码包含了几十个网络程序,这些示例程序都没有直接使用Sockets API。
    在此之外,无论是实习还是工作,虽然我写的程序都会通过TCP 协议与其他程序打交道,但我没有直接使用过Sockets API。对于TCP 网络编程,我认为核心是处理“三个半事件”,见§6.4.1 “TCP 网络编程本质论”。程序员的主要工作是在事件处理函数中实现业务逻辑,而不是和Sockets API“较劲”。
    这里还是没有说清楚“网络编程”是什么,请继续阅读后文§A.1.5“网络编程的各种任务角色”。
    A.1.2 学习网络编程有用吗
    以上说的是比较底层的网络编程,程序代码直接面对从TCP 或UDP 收到的数据以及构造数据包发出去。在实际工作中,另一种常见的情况是通过各种client library来与服务端打交道,或者在现成的框架中填空来实现server,或者采用更上层的通信方式。比如用libmemcached 与memcached 打交道,使用libpq 来与PostgreSQL 打交道,编写Servlet 来响应HTTP 请求,使用某种RPC 与其他进程通信,等等。这些情况都会发生网络通信,但不一定算作“网络编程”。如果你的工作是前面列举的这些,学习TCP/IP 网络编程还有用吗?
    我认为还是有B要学一学,至少在troubleshooting 的时候有用。无论如何,这些library 或framework 都会调用底层的Sockets API 来实现网络功能。当你的程序遇到一个线上问题时,如果你熟悉Sockets API,那么从strace 不难发现程序卡在哪里,尽管可能你没有直接调用这些Sockets API。另外,熟悉TCP/IP 协议、会用tcpdump 也非常有助于分析解决线上网络服务问题。
    A.1.3 在什么平台上学习网络编程
    对于服务端网络编程,我建议在Linux 上学习。
    如果在10 年前,这个问题的答案或许是FreeBSD,因为FreeBSD“根正苗红”,在2000 年那一次互联网浪潮中扮演了重要角色,是很多公司SX的免费服务器操作系统。2000 年那会儿Linux 还远未成熟,连epoll 都还没有实现。(FreeBSD 在2001年发布4.1 版,加入了kqueue,从此C10k 不是问题。)
    10 年后的今天,事情起了一些变化,Linux 成为市场份额ZD的服务器操作系统。在Linux 这种大众系统上学网络编程,遇到什么问题会比较容易解决。因为用的人多,你遇到的问题别人多半也遇到过;同样因为用的人多,如果真的有什么内核bug,很快就会得到修复,至少有work around 的办法。如果用别的系统,可能一个问题发到论坛上半个月都不会有人理。从内核源码的风格看,FreeBSD 更干净整洁,注释到位,但是无奈它的市场份额远不如Linux,学习Linux 是更好的技术投资。
    A.1.4 可移植性重要吗
    写网络程序要不要考虑移植性?要不要跨平台?这取决于项目需要,如果贵公司做的程序要卖给其他公司,而对方可能使用Windows、Linux、FreeBSD、Solaris、AIX、HP-UX 等等操作系统,这时候当然要考虑移植性。如果编写公司内部的服务器上用的网络程序,那么大可只关注一个平台,比如Linux。因为编写和维护可移植的网络程序的代价相当高,平台间的差异可能远比想象中大,即便是POSIX 系统之间也有不小的差异(比如Linux 没有SO_NOSIGPIPE 选项,Linux 的pipe(2) 是单向的,而FreeBSD 是双向的),错误的返回码也大不一样。
    我就不打算把mudu往Windows 或其他操作系统移植。如果需要编写可移植的网络程序,我宁愿用libevent、libuv、Java Netty 这样现成的库,把“脏活、累活”留给别人。
    A.1.5 网络编程的各种任务角色
    计算机网络是个big topic,涉及很多人物和角色,既有开发人员,也有运维人员。比方说:公司内部两台机器之间ping 不通,通常由网络运维人员解决,看看是布线有问题还是路由器设置不对;两台机器能ping 通,但是程序连不上,经检查是本机防火墙设置有问题,通常由系统管理员解决;两台机器能连上,但是丢包很严重,发现是网卡或者交换机的网口故障,由硬件维修人员解决;两台机器的程序能连上,但是偶尔发过去的请求得不到响应,通常是程序bug,应该由开发人员解决。
    本文主要关心开发人员这一角色。下面简单列出一些我能想到的跟网络打交道的编程任务,其中前三项是面向网络本身,后面几项是在计算机网络之上构建信息系统。
    1. 开发网络设备,编写防火墙、交换机、路由器的固件(firmware)。
    2. 开发或移植网卡的驱动。
    3. 移植或维护TCP/IP 协议栈(特别是在嵌入式系统上)。
    4. 开发或维护标准的网络协议程序,HTTP、FTP、DNS、SMTP、POP3、NFS。
    5. 开发标准网络协议的“附加品”,比如HAProxy、squid、varnish 等Web loadbalancer。
    6. 开发标准或非标准网络服务的客户端库,比如ZooKeeper 客户端库、memcached客户端库。
    7. 开发与公司业务直接相关的网络服务程序,比如即时聊天软件的后台服务器、网游服务器、金融交易系统、互联网企业用的分布式海量存储、微博发帖的内部广播通知等等。
    8. 客户端程序中涉及网络的部分,比如邮件客户端中与POP3、SMTP 通信的部分,以及网游的客户端程序中与服务器通信的部分。
    本文所指的“网络编程”专指第7 项,即在TCP/IP 协议之上开发业务软件。换句话说,不是用Sockets API 开发mudu这样的网络库,而是用libevent、muduo、Netty、gevent 这样现成的库开发业务软件,mudu自带的十几个示例程序是业务软件的代表。
    A.1.6 面向业务的网络编程的特点
    与通用的网络服务器不同,面向公司业务的专用网络程序有其自身的特点。
    业务逻辑比较复杂,而且时常变化 如果写一个HTTP 服务器,在大致实现HTTP 1.1 标准之后,程序的主体功能一般不会有太大的变化,程序员会把时间放在性能调优和bug 修复上。而开发针对公司业务的专用程序时,功能说明书(spec)很可能不如HTTP 1.1 标准那么细致明确。更重要的是,程序是快速演化的。以即时聊天工具的后台服务器为例,可能DY版只支持在线聊天;几个月之后发布第二版,支持离线消息;又过了几个月,第三版支持隐身聊天;随后,第四版支持上传头像;如此等等。这要求程序员能快速响应新的业务需求,公司才能保持竞争力。由于业务时常变化(假设每月一次版本升级),也会降低服务程序连续运行时间的要求。相反,我们要设计一套流程,通过轮流重启服务器来完成平滑升级(§9.2.2)。
    不一定需要遵循公认的通信协议标准 比方说网游服务器就没什么协议标准,反正客户端和服务端都是本公司开发的,如果发现目前的协议设计有问题,两边一起改就行了。由于可以自己设计协议,因此我们可以绕开一些性能难点,简化程序结构。比方说,对于多线程的服务程序,如果用短连接TCP 协议,为了优化性能通常要精心设计accept 新连接的机制2,避免惊群并减少上下文切换。但是如果改用长连接,用Z简单的单线程accept 就行了。
    程序结构没有定论 对于高并发大吞吐的标准网络服务,一般采用单线程事件驱动的方式开发,比如HAProxy、lighttpd 等都是这个模式。但是对于专用的业务系统,其业务逻辑比较复杂,占用较多的CPU 资源,这种单线程事件驱动方式不见得能发挥现在多核处理器的优势。这留给程序员比较大的自由发挥空间,做好了“横扫千军”,做烂了一败涂地。我认为目前one loop per thread 是通用性较高的一种程序结构,能发挥多核的优势,见§3.3 和§6.6。
    性能评判的标准不同 如果开发httpd 这样的通用服务,B然会和开源的Nginx、lighttpd 等高性能服务器比较,程序员要投入相当的精力去优化程序,才能在市场上占有一席之地。而面向业务的专用网络程序不一定是Ibound,也不一定有开源的实现以供对比性能,优化方向也可能不同。程序员通常更加注重功能的稳定性与开发的便捷性。性能只要一代比一代强即可。
    网络编程起到支撑作用,但不处于主导地位 程序员的主要工作是实现业务逻辑,而不只是实现网络通信协议。这要求程序员深入理解业务。程序的性能瓶颈不一定在网络上,瓶颈有可能是CPU、Disk IO、数据库等,这时优化网络方面的代码并不能提高整体性能。只有对所在的领域有深入的了解,明白各种因素的权衡(trade-off),才能做出一些有针对性的优化。现在的机器上,简单的并发长连接echo服务程序不用特别优化就做到十多万qps,但是如果每个业务请求需要1ms 密集计算,在8 核机器上充其量能达到8 000 qps,优化I不如去优化业务计算(如果投入产出合算的话)。
    A.1.7 几个术语
    互联网上的很多“口水战”是由对同一术语的不同理解引起的,比如我写的《多线程服务器的适用场合》3,就曾经被人说是“挂羊头卖狗肉”,因为这篇文章中举的master 例子“根本就算不上是个网络服务器。因为它的瓶颈根本就跟网络无关。”
    网络服务器 “网络服务器”这个术语确实含义模糊,到底指硬件还是软件?到底是服务于网络本身的机器(交换机、路由器、防火墙、NAT),还是利用网络为其他人或程序提供服务的机器(打印服务器、文件服务器、邮件服务器)?每个人根据自己熟悉的领域,可能会有不同的解读。比方说,或许有人认为只有支持高并发、高吞吐量的才算是网络服务器。
    为了避免无谓的争执,我只用“网络服务程序”或者“网络应用程序”这种含义明确的术语。“开发网络服务程序”通常不会造成误解。
    客户端?服务端? 在TCP 网络编程中,客户端和服务端很容易区分,主动发起连接的是客户端,被动接受连接的是服务端。当然,这个“客户端”本身也可能是个后台服务程序,HTTP proxy 对HTTP server 来说就是个客户端。
    客户端编程?服务端编程? 但是“服务端编程”和“客户端编程”就不那么好区分了。比如Web crawler,它会主动发起大量连接,扮演的是HTTP 客户端的角色,但似乎应该归入“服务端编程”。又比如写一个HTTP proxy,它既会扮演服务端--被动接受Web browser 发起的连接,也会扮演客户端--主动向HTTP server 发起连接,它究竟算服务端还是客户端?我猜大多数人会把它归入服务端编程。
    那么究竟如何定义“服务端编程”?
    服务端编程需要处理大量并发连接?也许是,也许不是。比如云风在一篇介绍网游服务器的博客4 中就谈到,网游中用到的“连接服务器”需要处理大量连接,而“逻辑服务器”只有一个外部连接。那么开发这种网游“逻辑服务器”算服务端编程还是客户端编程呢?又比如机房的服务进程监控软件,并发数跟机器数成正比,至多也就是两三千的并发连接。(再大规模就C出本书的范围了。)
    我认为,“服务端网络编程”指的是编写没有用户界面的长期运行的网络程序,程序默默地运行在一台服务器上,通过网络与其他程序打交道,而不B和人打交道。与之对应的是客户端网络程序,要么是短时间运行,比如wget;要么是有用户界面(无论是字符界面还是图形界面)。本文主要谈服务端网络编程。
    1978114758
    1
    • 商品详情
    • 内容简介

    售后保障

    最近浏览

    猜你喜欢

    该商品在当前城市正在进行 促销

    注:参加抢购将不再享受其他优惠活动

    x
    您已成功将商品加入收藏夹

    查看我的收藏夹

    确定

    非常抱歉,您前期未参加预订活动,
    无法支付尾款哦!

    关闭

    抱歉,您暂无任性付资格

    此时为正式期SUPER会员专享抢购期,普通会员暂不可抢购