理解HTTP协议中的multipart/form-data
前提之前在写一个通用HTTP组件的时候遇到过媒体(Media)类型multipart/form-data的封装问题,这篇文章主要简单介绍一下HTTP协议中媒体类型multipart/form-data的定义、应用和简单实现。 multipart/form-data的定义媒体类型multipart/form-data遵循multipart MIME数据流定义(该定义可以参考Section 5.1 - RFC2046),大概含义就是:媒体类型multipart/form-data的数据体由多个部分组成,这些部分由一个固定边界值(Boundary)分隔。 multipart/form-data请求体布局multipart/form-data请求体的布局如下: 1234567891011121314151617181920# 请求头 - 这个是必须的,需要指定Content-Type为multipart/form-data,指定唯一边界值Content-Type: multipart/form-data; boundary=${Boundary}# 请求体--${ ...
基于Docker部署全新一套中间件环境 - 命令行极速版
背景本文是一篇流水账笔记,记录基于命令行和Docker快速部署一个全新环境的中间件,精通多种中间件的安装(与卸载)。 获取Docker中运行的组件的内网IP【这里指的Docker环境内网,不是宿主机的网络】: docker inspect —format ‘{{ .NetworkSettings.IPAddress }}’ {容器实例名称} 本文基于CentOS7.x和当前最新的Docker版本编写,注意其他操作系统不一定合适。 安装Docker移除已经存在的旧版本Docker: 折叠命令: 12345678sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate ...
JDK中Lambda表达式的序列化与SerializedLambda的巧妙使用
前提笔者在下班空余时间想以Javassist为核心基于JDBC写一套摒弃反射调用的轻量级的ORM框架,过程中有研读mybatis、tk-mapper、mybatis-plus和spring-boot-starter-jdbc的源代码,其中发现了mybatis-plus中的LambdaQueryWrapper可以获取当前调用的Lambda表达式中的方法信息(实际上是CallSite的信息),这里做一个完整的记录。本文基于JDK11编写,其他版本的JDK不一定合适。 神奇的Lambda表达式序列化之前在看Lambda表达式源码实现的时候没有细看LambdaMetafactory的注释,这个类顶部大量注释中其中有一段如下: 简单翻译一下就是:可序列化特性。一般情况下,生成的函数对象(这里应该是特指基于Lambda表达式实现的特殊函数对象)不需要支持序列化特性。如果需要支持该特性,FLAG_SERIALIZABLE(LambdaMetafactory的一个静态整型属性,值为1 << 0)可以用来表示函数对象是序列化的。一旦使用了支持序列化特性的函数对象,那么它们以Seriali ...
CentOS7.x基于源码编译和安装Nginx
背景笔者日常工作里面包括了云上运维工作,包括(业务)云服务器的管理、云中间件和云服务器自建中间件的部署和维护。云负载均衡产品一般称为CLB或者SLB,从实现上猜测是基于Nginx进行二次开发。由于云负载均衡中间件的费用比较高,一般选用云服务器自建Nginx集群,那么就需要”精通”Nginx的安装(和卸载)过程。写本文的时间为2021-11前后,所用的系统和软件版本如下: 系统或软件 版本 CentOS 7.x Nginx 1.20.1 前置依赖安装手动编译Nginx源码之前,至少需要安装这几个依赖: 软件包 功能 链接 gcc、gcc-c++ GCC编译器 gcc、gcc-c++ pcre、pcre-devel Perl Compatible Regular Expressions,perl兼容的正则表达式库 pcre zlib、zlib-devel 提供了很多种压缩和解压缩方式 zlib openssl、openssl-devel 密码算法、常用的密钥和证书封装管理功能及TLS/SSL协议支持 openssl 安装gc ...
Hexo系列 - 私有化部署《人生重启模拟器》
前提前段时间,H5页面游戏《人生重启模拟器》发布,大获好评。 《人生重启模拟器》源码仓库:https://github.com/VickScarlet/lifeRestart 部署环境:腾讯云COS 本地环境版本:Node.js => v12.16.1、npm => 8.0.0 查看项目的LICENSE: 明确是MIT License,条款如下: 可以使用,复制和修改软件 以免费使用软件或出售 唯一的限制是,它是必须附有MIT授权协议 从这个LICENSE来看,只要在部署的时候,不删除源码中原有的LICENSE文件即可,如果有入口或者展示界面引用了这个项目,需要把LICENSE文件带上。 下载源码和本地编译下载源码: 123cd 你的目录git clone https://github.com/VickScarlet/lifeRestartcd lifeRestart 查看lifeRestart/package.json文件: 得知: npm install:本地安装依赖 npm run dev:开发模式运行 npm run build:生产模式打包 那么 ...
13万字详细分析JDK中Stream的实现原理
前提Stream是JDK1.8中首次引入的,距今已经过去了接近8年时间(JDK1.8正式版是2013年底发布的)。Stream的引入一方面极大地简化了某些开发场景,另一方面也可能降低了编码的可读性(确实有不少人说到Stream会降低代码的可读性,但是在笔者看来,熟练使用之后反而觉得代码的可读性提高了)。这篇文章会花巨量篇幅,详细分析Stream的底层实现原理,参考的源码是JDK11的源码,其他版本JDK可能不适用于本文中的源码展示和相关例子。 这篇文章花费了极多时间和精力梳理和编写,希望能够帮助到本文的读者 Stream是如何做到向前兼容的Stream是JDK1.8引入的,如要需要JDK1.7或者以前的代码也能在JDK1.8或以上运行,那么Stream的引入必定不能在原来已经发布的接口方法进行修改,否则必定会因为兼容性问题导致老版本的接口实现无法在新版本中运行(方法签名出现异常),猜测是基于这个问题引入了接口默认方法,也就是default关键字。查看源码可以发现,ArrayList的超类Collection和Iterable分别添加了数个default方法: 1234567891 ...
Java协程编程之Loom项目尝鲜
前提之前很长一段时间关注JDK协程库的开发进度,但是前一段时间比较忙很少去查看OpenJDK官网的内容。Java协程项目Loom(因为项目还在开发阶段,OpenJDK给出的官网https://openjdk.java.net/projects/loom中只有少量Loom项目相关的信息)已经在2018年之前立项,目前已经发布过基于JDK17编译和JDK18编译等早期版本,笔者在下载Loom早期版本的时候只找到JDK18编译的版本: 下载入口在:https://jdk.java.net/loom 由于该JDK版本过高,目前可以使用主流IDE导入Loom-JDK-18+9进行代码高亮和语法提醒,暂时找不到方法进行编译,暂时使用该JDK执行目录下的的javac命令脚本进行编译,使用java命令脚本运行。 Loom项目简单介绍 Loom - Fibers, Continuations and Tail-Calls for the JVM Loom项目的标题已经凸显了引入的三大新特性: Fibers:几年前看过当时的Loom项目的测试代码就是使用Fiber这个API(现在这个API已经被 ...
基于Java和Bytemd用120行代码实现一个桌面版Markdown编辑器
前提某一天点开掘金的写作界面的时候,发现了内置Markdown编辑器有一个Github的图标,点进去就是一个开源的Markdown编辑器项目bytemd(https://github.com/bytedance/bytemd): 这是一个NodeJs项目,由字节跳动提供。联想到之前业余的时候做过一些Swing或者JavaFx的Demo,记得JavaFx中有一个组件WebView已经支持Html5、CSS3和ES5,这个组件作为一个嵌入式浏览器,可以轻松地渲染一个URL里面的文本内容或者直接渲染一个原始的Html字符串。另外,由于原生的JavaFx的视觉效果比较丑,可以考虑引入Swing配合IntelliJ IDEA的主题提供更好的视觉效果。本文的代码基于JDK11开发。 引入依赖很多人吐槽过Swing组件的视觉效果比较差,原因有几个: 技术小众,现在有更好的组件进行混合开发和跨平台开发 基于上一点原因,导致很少人会去开发Swing组件的UI,其实Swing的每个组件都可以重新实现UI的表现效果 compose-jb(JetBrains)组件很晚才发布出来,刚好碰上Swing官方停 ...
透视RPC协议:SOFA-BOLT协议源码分析
前提最近在看Netty相关的资料,刚好SOFA-BOLT是一个比较成熟的Netty自定义协议栈实现,于是决定研读SOFA-BOLT的源码,详细分析其协议的组成,简单分析其客户端和服务端的源码实现。 吐槽一下:SOFA-BOLT的代码缩进和FastJson类似,变量名称强制对齐,对于一般开发者来说看着源码会有不适感 当前阅读的源码是2021-08左右的SOFA-BOLT仓库的master分支源码。 SOFA-BOLT简单介绍SOFA-BOLT是蚂蚁金融服务集团开发的一套基于Netty实现的网络通信框架,本质是一套Netty私有协议栈封装,目的是为了让开发者能将更多的精力放在基于网络通信的业务逻辑实现上,而不是过多的纠结于网络底层NIO的实现以及处理难以调试的网络问题和Netty二次开发问题。SOFA-BOLT的架构设计和功能如下: 上图来源于SOFA-BOLT官网https://www.sofastack.tech/projects/sofa-bolt/overview SOFA-BOLT协议透视由于SOFA-BOLT协议是基于Netty实现的自定义协议栈,协议本身的实现可以快 ...
冷饭新炒:理解布隆过滤器算法的实现原理
前提这是《冷饭新炒》系列的第六篇文章。 本文会翻炒一个用途比较广的算法 - 布隆过滤器算法。 布隆过滤器的一些概念主要包括: 简介 算法 参数 优势和劣势 布隆过滤器简介布隆过滤器是一种空间高效概率性的数据结构(百科中原文是a space-efficient probabilistic data structure),该数据结构于1970年由Burton Howard Bloom提出,作用是测试一个元素是否某个集合的一个成员。布隆过滤器是可能出现false positive(这个是专有名词”假阳性”,可以理解为误判的情况,下文如果用到这个名词会保留英文单词使用)匹配的,换言之,布隆过滤器在使用的时候有可能返回结果”可能存在于集合中”或者”必定不存在于集合中”。 布隆过滤器算法描述在场景复杂的网络爬虫中,爬取到的网页URL依赖有可能成环,例如在URL-1页面中展示了URL-2,然后又在URL-2中的页面展示了URL-1,这个时候需要一种方案记录和判断历史访问过的URL。这个时候可能会想到下面的方案: 方案一:使用数据库存储已经访问过的URL,例如MySQL表中基于URL建立唯一索 ...