文章目录

  • 简介
  • 本文的目标
  • 支持多个图片服务
  • http2处理器
  • 处理页面和图像
  • 价值上亿的速度优化方案
  • 总结

简介

其实软件界最赚钱的不是写代码的,写代码的只能叫马龙,高级点的叫做程序员,都是苦力活。那么有没有高大上的职业呢?这个必须有,他们的名字就叫做咨询师。

咨询师就是去帮企业做方案、做架构、做优化的,有时候一个简单的代码改动、一个架构的调整都可以让软件或者流程更加高效的运行,从而为企业节省上亿的开支。

今天除了要给大家介绍一下如何在netty中同时支持http和https协议之外,还给大家介绍一个价值上亿的网站数据优化方案,有了这个方案,年薪百万不是梦!

本文的目标

本文将会给大家介绍一下如何在一个netty服务中同时支持http和http2两种协议,在这两个服务器中,提供了对多图片的访问支持,我们介绍如何从服务器端返回多个图片。最后介绍一个价值上亿的速度优化方案,肯定大家会受益匪浅。

支持多个图片服务

对于服务器端来说,是通过ServerBootstrap来启动服务的,ServerBootstrap有一个group方法用来指定acceptor的group和client的group。

    public ServerBootstrap group(EventLoopGroup group) public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup)

当然你可以指定两个不同的group,也可以指定同一个group,它提供了两个group方法,效果上没太大的区别。

这里我们现在主服务器中创建一个EventLoopGroup,然后将其传入到ImageHttp1Server和ImageHttp2Server中。然后分别在两个server中调用group方法,然后配置handler即可。

先看一下ImageHttp1Server的构造:

        ServerBootstrap b = new ServerBootstrap();b.option(ChannelOption.SO_BACKLOG, 1024);b.group(group).channel(NioServerSocketChannel.class).handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch){ch.pipeline().addLast(new HttpRequestDecoder(),new HttpResponseEncoder(),new HttpObjectAggregator(MAX_CONTENT_LENGTH),new Http1RequestHandler());}});

我们传入了netty自带的HttpRequestDecoder、HttpResponseEncoder和HttpObjectAggregator。还有一个自定义的Http1RequestHandler。

再看一下ImageHttp2Server的构造:

ServerBootstrap b = new ServerBootstrap();b.option(ChannelOption.SO_BACKLOG, 1024);b.group(group).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch)  {ch.pipeline().addLast(sslCtx.newHandler(ch.alloc()), new CustProtocolNegotiationHandler());}});

为了简单起见,我们默认如果从http来访问的话,就使用http1服务,如果是从https来访问的话,就使用http2服务。

所以在http2服务中,我们只需要自定义ProtocolNegotiationHandler即可,而不用处理clear text升级的请求。

http2处理器

在TLS环境中,我们通过自定义CustProtocolNegotiationHandler,继承自ApplicationProtocolNegotiationHandler来进行客户端和服务器端协议的交互。

对于http2协议来说,使用了netty自带的InboundHttp2ToHttpAdapterBuilder和HttpToHttp2ConnectionHandlerBuilder将http2 frame转换成为http1的FullHttpRequest对象。这样我们直接处理http1格式的消息即可。

转换过程如下:

DefaultHttp2Connection connection = new DefaultHttp2Connection(true);InboundHttp2ToHttpAdapter listener = new InboundHttp2ToHttpAdapterBuilder(connection).propagateSettings(true).validateHttpHeaders(false).maxContentLength(MAX_CONTENT_LENGTH).build();ctx.pipeline().addLast(new HttpToHttp2ConnectionHandlerBuilder().frameListener(listener).connection(connection).build());ctx.pipeline().addLast(new Http2RequestHandler());

转换转换的http2 handler和普通的http1的handler唯一不同的是需要额外设置一个streamId属性到请求头和响应头中。

并且不需要处理http1特有的100-continue和KeepAlive。其他的和http1 handler没什么两样。

处理页面和图像

因为我们使用转换器将http2的frame转换成了http1的普通对象,所以对请求相应的页面和图像来说,跟http1的处理没什么太大区别。

对于页面来说,我们需要获取要返回的html,然后设置CONTENT_TYPE为"text/html; charset=UTF-8",返回即可:

    private void handlePage(ChannelHandlerContext ctx, String streamId,  FullHttpRequest request) throws IOException {ByteBuf content =ImagePage.getContent();FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, content);response.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8");sendResponse(ctx, streamId, response, request);}

对于图像来说,我们获取到要返回的图像,将其转换成为ByteBuf,然后设置CONTENT_TYPE为"image/jpeg",返回即可:

    private void handleImage(String id, ChannelHandlerContext ctx, String streamId,FullHttpRequest request) {ByteBuf image = ImagePage.getImage(parseInt(id));FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, image);response.headers().set(CONTENT_TYPE, "image/jpeg");sendResponse(ctx, streamId, response, request);}

这样,我们就能够在netty服务器端同时处理页面请求和图片请求了。

价值上亿的速度优化方案

终于要到本文中最精彩的部分了,价值上亿的速度优化方案是什么呢?

在讲这个方案之前,先给大家讲一个抗洪抢险的故事。有两个县都住在一条大河的旁边。这条大河很不安稳,经常会发洪灾,但是两个县的县长做法很不同。

A县的县长认真负责,派人定期巡逻检查所属的河段,筑堤、种树、巡视,一刻都放松,在他的任期平平安安,没有发生任何洪水溃堤的情况。

B县的县长从来不巡检,一道河水泛滥的时候,B县长就组织人抗洪抢险,然后媒体全都报道的是B县长抗洪的丰功伟绩,最后B县长由于政绩突出,升任市长。

好了,故事讲完了,接下来是我们的优化。不管是用户请求页面还是图片,最终都需要调用ctx.writeAndFlush(response)方法进行响应回写。

如果将其放入一个定时任务中,来定时执行,如下所示:

ctx.executor().schedule(new Runnable() {@Overridepublic void run() {ctx.writeAndFlush(response);}}, latency, TimeUnit.MILLISECONDS);

那么服务器在经过latency指定的毫秒之后,才会发送对应的响应。比如这里我们设置latency的值为5秒。

当然5秒是不能够让人满意的,于是领导或者客户找到你,说让你给优化一下。你说这个性能问题是很难的,涉及到了麦克斯韦方程组和热力学第三定律,需要一个月时间。领导说好,撸起袖子加油干,下个月给你工资涨50%。

一个月后,你把latency改成2.5秒,性能提升了100%,这个优化值不值几个亿?

总结

当然,上一节给大家开个玩笑,不过在netty响应中使用定时任务的技巧,大家也应该牢牢掌握,原因你懂的!

本文的例子可以参考:learn-netty4

本文已收录于 http://www.flydean.com/34-netty-multiple-server/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

netty系列之:一个价值上亿的网站速度优化方案相关推荐

  1. 价值上亿元的IT机房,都有哪些设备?

    数据中心机房建设是一个系统工程,它由主机房(包括网络交换机.服务器群.存储器.数据输入/输出配线.通信区和网络监控终端等).基本工作间(包括办公室.缓冲间.走廊.更衣室等).第一类辅助房间(包括维修室 ...

  2. 索引一般加在什么字段上_在价值上亿的豪华游轮做服务员,是什么体验?网友:也就一般般吧...

    对于工薪阶级的我们来说,看到豪华游轮的第一反应是:听起来就很贵,惹不起,惹不起.因为就国内最便宜的游轮单程收费就是2000起步,更别提那些超豪华的游轮,入门级的房型:价格7499美元,换算成人民币就是 ...

  3. 一场直播获利6亿,看“美ONE”如何打造出“李佳琦”这样一个价值过亿的IP!!!

    李佳琦,一个美妆圈让人又爱又恨的男人,一个带货怪物,一个赚钱机器.据说每50个进入李佳琦直播间或者看过他拍的视频的女生,其中90%都会剁手下单. 作为一个男性美妆博主,抖音开通两个月涨粉1400万,淘 ...

  4. 一个网站SEO优化方案

    首先,前端/页编人员主要负责站内优化,主要从四个方面入手: 第一个,站内结构优化 合理规划站点结构(1.扁平化结构 2.辅助导航.面包屑导航.次导航) 内容页结构设置(最新文章.推荐文章.热门文章.增 ...

  5. 一个医院网站的优化方案 方方面面皆须做好

    一个医院网站的优化方案 方方面面皆须做好 大家好,我是虚子雨,最近在给北京东苑中医医院的一个网站做优化,很忙,好久没怎么写文章,今天特意抽时间来用心的写这篇文章.废话少说吧,步入正题.北京东苑中医医院 ...

  6. 一个价值10亿的教训

    这几天我的读者群在讨论互联网的破局方法,大家讨论到互联网的单点突破.互联网单点突破最早是周鸿祎提出来的方法论. 我创业的时候因为没有做到单点突破,丧失了一个10亿的机会,结合我的经验教训,今天谈谈互联 ...

  7. 这些价值上亿美元的网站,背后居然都只有一个程序员!

    一个程序员,能顶一个团队,你一定想不到 你一定用过Google吧?有没有觉得这个页面极其简单,仿佛一个程序员就可以做出来? 然而事实并非如此,这个页面背后有个名叫Google Web Servers的 ...

  8. 前端如何展示一个有上亿数据的树结构

    需求描述 数据上亿,有数千个从属于根节点的一级子节点: 每个一级子节点有数个到数万个二级子节点: 二级子节点可能有三级子节点: 子节点的最多层深不定(即,也许可能有 10 层): 需求分析 当面临一个 ...

  9. 一个完整和详细的网站SEO优化解决方案

    祥云平台上的完整SEO优化解决方案包含四个主要组件: 第一:网站前端设计师 第二:网站内容录入人员 第三:网站优化和推广人员 第四:背景数据分析师 接下来,我们将为这四个部门分配工作. 首先,网站的前 ...

最新文章

  1. Bresenham 生成直线
  2. iOS中 最新微信支付/最全的微信支付教程详解 韩俊强的博客
  3. 洛谷P4173:残缺的字符串(FFT、通配符匹配)
  4. 山东鲁能轨道智能巡检机器人_温湿度传感器在轨道巡检机器人中的应用
  5. 【kubernetes / k8s 踩坑记录】一定要关闭SWAP
  6. Linux系统NFS什么意思,挂载NFS到底是什么概念
  7. 【随记】Q号解除限制一波三折
  8. python3 ocr_python3 ocr 识别图片文字(CSDN验证码90%通过)
  9. 只会java_只会码代码的你和Java工程师之间的差距有大?
  10. bootstrap 页面垂直居中_前端布局之——水平垂直居中
  11. 死磕Android_App 启动过程(含 Activity 启动过程)
  12. Transformers Assemble(PART I)
  13. 超详细SPSS主成分分析计算指标权重(一)
  14. 嵌入式C语言编程中经验教训总结(一) 详解const、static和volatile
  15. etc fstab 详解linux,Linux下/etc/fstab文件详解
  16. 联想服务器重装系统后usb无法启动,联想启天装win7系统的详细教程完美解决USB不能用的问题...
  17. c语言写按键控制蜂鸣器,单片机按键控制蜂鸣器演奏音乐
  18. Unity技术手册-编辑器基础入门万字大总结
  19. precede和previous_preceding,previous,prior辨析.ppt
  20. c# DGV导出excel 使用object类型数组,解决string类型需双击后或分列才可运算的异常

热门文章

  1. BST(Binary Search Tree 二叉查找树模版)
  2. golang 使用 redis 的教程
  3. 简单的IDT HOOK介绍
  4. _variant_t和_bstr_t有什么区别
  5. 单元测试源码分析之二Mockito自动装配和插桩
  6. 设计模式---组合模式
  7. 大厂提供什么样的软硬件来吸引人才?
  8. Java多线程知识小抄集(三)
  9. 惊!空 struct 地址竟然不相等
  10. 【今晚7点半】:主编对话Netless白板创始人伍双