首页 文章 精选 留言 我的

精选列表

搜索[快速入门],共10000篇文章
优秀的个人博客,低调大师

【Spark Summit EU 2016】快速数据处理最佳拍档:Spark+ Ignite

更多精彩内容参见云栖社区大数据频道https://yq.aliyun.com/big-data;此外,通过Maxcompute及其配套产品,低廉的大数据分析仅需几步,详情访问https://www.aliyun.com/product/odps。 本讲义出自Christos Erotocritou在Spark Summit EU 2016上的演讲,主要介绍了Apache的通用数据库缓存系统——Ignite项目,Apache Ignite允许用户将常用的热数据储存在内存中,它支持分片和复制两种方式,让开发者可以均匀地将数据分布式到整个集群的主机上。同时,Ignite还支撑任何底层存储平台,不管是RDBMS、NoSQL,又或是HDFS。 除此之外,Christos Erotocritou还介绍了Hadoop与Spark进行集成以及Spark与Ignite集成,以及内存文件系统等相关内容。

优秀的个人博客,低调大师

MaxCompute2.0性能评测:更强大、更高效之上的更快速

MaxCompute2.0(原Odps):通过性能评测,MaxCompute2.0离线计算比同类产品Hive2.0 on Tez性能优势快约90%以上;MaxCompute2.0从新一代执行引擎到编译引擎、基于代价的优化器全流程针对性能提升做出了卓越改进。 本次评测侧重于已发布的MaxCompute2.0与离线处理同类竞品及线上稳定版本的性能对比,通过测试我们看到MaxCompute2.0在功能上更强大、使用和发布更新更高效、开放生态的同时针对线上作业占比80%以上的Sql以及其中占比约50%的Sql离线批量计算性能有极大提升。 一,新一代执行引擎        MaxCompute2.0开发了新一代执行引

优秀的个人博客,低调大师

阿里云持续交付-快速可靠地交付高质量软件

文/戴蒙 拥有3万多人的阿里巴巴,线上有上万个应用,上亿的用户即时在线,每天有几百个应用在线上更新,就像在时速200公里的高速公路上横穿马路维修栅栏一样,时刻保持着心惊胆战,而保护这个过程的体系就是阿里巴巴持续交付工具与实践。 现代开发企业中如何做好持续交付是一件异常重要的事情,在互联网企业中更是如此。而阿里巴巴在这么多年的研发管理基础上,对如何做好持续交付提出了一套全新的模型与实践。 阿里技术保障部产品专家戴蒙在“2016云栖大会上海峰会”专场《“互联网+”架构及实践专场-企业级信息系统云化演进之路》中分享了阿里云持续交付打造高质量交付和高质量软件的经验。 本次演讲深度分析了阿里式的持续交付理论,同时分享如何通过工具提升研发管理实践效果。交互无小事,任何与客户有关的都是大事,做好了研发管理才能平安如意,如同登陆在月球虹湾里那么高效安稳。

优秀的个人博客,低调大师

「X」Embedding in NLP|神经网络和语言模型 Embedding 向量入门

在「X」Embedding in NLP 进阶系列中,我们介绍了自然语言处理的基础知识——自然语言中的 Token、N-gram 和词袋语言模型。今天,我们将继续和大家一起“修炼”,深入探讨神经网络语言模型,特别是循环神经网络,并简要了解如何生成 Embedding 向量。 01.深入了解神经网络 首先,简要回顾一下神经网络的构成,即神经元、多层网络和反向传播算法。如果还想更详细深入了解这些基本概念可以参考其他资源,如 CS231n 课程笔记。 在机器学习中,神经元是构成所有神经网络的基本单元。本质上,神经元是神经网络中的一个单元,它对其所有输入进行加权求和,并加上一个可选的偏置项。方程式表示如下所示: 在这里,代表上一层神经元的输出,代表这个神经元用来综合输出值的权重。 如果一个多层神经网络仅由上述方程中的加权和组成,我们可以将所有项合并为一个单一的线性层——这对于建模 Token 之间的关系或编码复杂文本并不是很理想。这就是为什么所有神经元在加权和之后都包含一个非线性激活函数,其中我们最熟知的例子就是修正线性单元(ReLU)函数: 对于大多数现代神经网络语言模型来说,高斯误差线性单元(GELU)激活函数更常见: 在这里,代表高斯累积分布函数,可以用 来表示。这个激活函数在上述的加权求和之后被应用。总而言之,一个单一的神经元看起来像这样: 为了学习更复杂的函数,我们可以将神经元堆叠起来——一个接一个地形成一个层。同一层中的所有神经元接收相同的输入;它们之间唯一的区别是权重 W 和偏置 b。我们可以用矩阵符号将上述方程表示一个单层: 在这里,w 是一个二维矩阵,包含应用于输入 x的所有权重;矩阵的每一行对应一个神经元的权重。这种类型的层通常被称为密集层或全连接层,因为所有输入x都连接到所有输出y。 我们可以将这两个层串联起来,创建一个基本的前馈网络: 这里我们引入了一个新的隐藏层 h1,它既没有直接连接到输入x,也没有直接连接到输出 y 。这一层有效地增加了网络的深度,增加了总的参数数量(多个权重矩阵 w )。此时,需要注意:随着添加的隐藏层增多,靠近输入层的隐藏值(激活值)与x更“相似”,而靠近输出的激活值则与 y 更相似。 我们在后续的文章中将基于这个原则探讨 Embedding 向量。隐藏层的概念对理解向量搜索至关重要。 前馈网络中单个神经元的参数可以通过一个称为反向传播的过程进行更新,本质上就是微积分中链式法则的重复应用。大家可以搜索一些专门讲解反向传播的课程,这些课程会介绍反向传播为什么对训练神经网络如此有效。这里我们不多做赘述,其基本过程如下所示: 通过神经网络输入一批数据。 计算损失。这通常是回归的 L2 损失(平方差)和分类的交叉熵损失。 使用这个损失来计算与最后一个隐藏层权重的损失梯度 。 计算通过最后一个隐藏层的损失,即 。 将这个损失反向传播到倒数第二个隐藏层的权重 。 重复步骤 4 和 5,直到计算出所有权重的偏导数。 在计算出与网络中所有权重相关的损失的偏导数后,可以根据优化器和学习率进行一次大规模的权重更新。这个过程会重复进行,直到模型达到收敛或所有轮次都完成。 02.循环神经网络 所有形式的文本和自然语言本质上都是顺序性的,也就是说单词 /Token 是一个接一个地处理的。看似简单的变化,比如增加一个单词、颠倒两个连续的 Token,或增加标点符号,都可能导致解释上的巨大差异。例如,“let's eat, Charles”和“let's eat Charles”两个短语完全是两回事。由于自然语言具备顺序性这一特性,因此循环神经网络(RNNs)是自然而然成为了语言建模的不二之选。 递归是一种独特的递归形式,其中函数是神经网络而不是代码。RNN 还有着生物学起源——人类大脑可以类比为一个(人工)神经网络,我们输入的单词或说出的话语都是生物学处理的结果。 RNN 由两个组成部分:1)一个标准的前馈网络和2)一个递归组件。前馈网络与我们在前一节中讨论的相同。对于递归组件,最后一个隐藏状态被反馈到输入中,以便网络可以保持先前的上下文。因此,先前的知识(以前一个时间步的隐藏层的形式)在每一个新的时间步被注入网络。 基于上述对 RNN 的宏观定义和解释,我们可以大致了解其实现方式以及为什么 RNN 在语义建模时表现良好。 首先,RNN 的循环结构使它们能够根据顺序捕捉和处理数据,其数据处理方式类似于人类说话、阅读和写作方式。此外,RNN 还可以有效访问来自较早时间的“信息”,比 n-gram 模型和纯前馈网络更能理解自然语言。 大家可以试试用 PyTorch 来实现一个 RNN。注意,这需要对 PyTorch 基础有深入的理解;如果对 PyTorch 还不太熟悉 ,建议大家先阅读该链接。 首先定义一个简单的前馈网络,然后将其扩展为一个简单的 RNN,先定义层: from torch import Tensor import torch.nn as nn class BasicNN(nn.Module): def __init__(self, in_dims: int, hidden_dims: int, out_dims: int): super(BasicNN, self).__init__() self.w0 = nn.Linear(in_dims, hidden_dims) self.w1 = nn.Linear(hidden_dims, out_dims) 注意,由于我们仅仅输出原始的逻辑值,我们还没有定义损失的样式。在训练时,可以根据实际情况加上某种标准,比如 nn.CrossEntropyLoss。 现在,我们可以实现前向传递: def forward(self, x: Tensor): h = self.w0(x) y = self.w1(h) return y 这两段代码片段结合在一起形成了一个非常基础的前馈神经网络。为了将其变成 RNN,我们需要从最后一个隐藏状态添加一个反馈回路回到输入: def forward(self, x: Tensor, h_p: Tensor): h = self.w0(torch.cat(x, h_p)) y = self.w1(h) return (y, h) 上述基本上就是全部步骤。由于我们现在增加了由 w0 定义的神经元层的输入数量,我们需要在 __init__中更新它的定义。现在让我们来完成这个操作,并将所有内容整合到一个代码片段中: import torch.nn as nn from torch import Tensor class SimpleRNN(nn.Module): def __init__(self, in_dims: int, hidden_dims: int, out_dims: int): super(RNN, self).__init__() self.w0 = nn.Linear(in_dims + hidden_dims, hidden_dims) self.w1 = nn.Linear(hidden_dims, out_dims) def forward(self, x: Tensor, h_p: Tensor): h = self.w0(torch.cat(x, h_p)) y = self.w1(h) return (y, h) 在每次前向传递中,隐藏层h的激活值与输出一起返回。这些激活值随后可以与序列中的每个新 Token一起再次传回模型中。这样一个过程如下所示(以下代码仅作示意): model = SimpleRNN(n_in, n_hidden, n_out) ... h = torch.zeros(1, n_hidden) for token in range(seq): (out, h) = model(token, ) 至此,我们成功定义了一个简单的前馈网络,并将其扩展为一个简单的 RNN。 03.语言模型 Embedding 我们在上面例子中看到的隐藏层有效地将已经输入到 RNN 的所有内容(所有 Token)进行编码。更具体而言,所有解析 RNN 已看到的文本所需的信息应包含在激活值 h 中。换句话说,h 编码了输入序列的语义,而由 h 定义的有序浮点值集合就是 Embedding 向量,简称为 Embedding。 这些向量表示广泛构成了向量搜索和向量数据库的基础。尽管当今自然语言的 Embedding 是由另一类称为 Transformer 的机器学习模型生成的,而不是 RNN,但本质概念基本相同:将文本内容编码为计算机可理解的 Embedding 向量。我们将在下一篇博客文章中详细讨论如何使用 Embedding 向量。 04.总结 我们在 PyTorch 中实现了一个简单的循环神经网络,并简要介绍了语言模型Embedding。虽然循环神经网络是理解语言的强大工具,并且可以广泛应用于各种应用中(机器翻译、分类、问答等),但它们仍然不是用于生成 Embedding 向量的 ML 模型类型。 在接下来的教程中,我们将使用开源的 Transformer 模型来生成 Embedding 向量,并通过对它们进行向量搜索和运算来展示向量的强大功能。此外,我们也将回到词袋模型的概念,看看这两者如何一起用于编码词汇和语义。敬请期待!

优秀的个人博客,低调大师

Opencv入门篇:简介与基本使用 | 京东物流技术团队

1 Opencv简介 Opencv是计算机视觉中经典的专用库,其支持多语言,跨平台,功能强大。Opencv-Python为Opencv提供了Python接口,使得使用者在Python中能够调用C/C++,在保证易读性和运行效率的前提下,实现所需的功能。 Opencv是由Gray Bradsky于1999年在英特尔创立,第一版于2000年问世。Vadim Pisarevsky加入Gary Bradsky,一起管理因特尔的俄罗斯软件Opencv团队。 2005年,Opencv用于Stanley,该车赢得了2005年DARPA挑战赛的冠军。后来,在Willow Garage的支持下,它的积极发展得以继续,由Gary Bradsky和Vadim Pisarevsky领导了该项目。Opencv现在支持与计算机视觉和机器学习有关的多种算法,并且正在日益扩展。 Opencv支持多种编程语言,例如C++, Python, Java等,并且可以再Windows , Linux , OS X , Android和IOS等不同平台上使用。基于CUDA和OpenCL的高速GPU操作的接口也在积极开发中。 Opencv-Python是用于Opencv的Python API,结合了Opencv C++ API和Python语言的最佳特性。 1.1 Opencv-Python Opencv-Python是旨在解决计算机视觉问题的专用库 Python是由Guidovan Rossum发起的通用编程语言,很快就非常流行,主要是因为他的简单性和代码可读性。它使得程序员可以用较少的代码行表达想法,而不会降低可读性。 与C/C++之类的语言,Python速度较慢。也就是说,可以使用C/C++轻松扩展Python,这使得我们能够用C/C++编写计算机密集型代码并创建可用作Python模块的Python包装器。它给我们带来了两个好处: 首先,代码与原始C/C++代码一样快(因为它是在后台运行的实际C++代码), 其次,在Python中比C/C++编写代码更容易。Opencv-Python是原始Opencv C++实现的Python包装器。 Opencv-Python利用了Numpy,这是一个高度优化的库,用于使用MATLAB样式的语言进行数值运算。所有Opencv数组结构都与Numpy数组相互转换。这也使与使用Numpy的其他库(例如Scipy和Matplotlib)的集成变得更加容易。 1.2 应用领域 人机互动 物体识别 图像分割 人脸识别 动作识别 运动跟踪 机器人 运动分析 机器视觉 结构分析 汽车安全驾驶 如上所述,opencv的功能十分强大,在各个领域大放异彩,由浅入深,本次我们先介绍图像编辑,简单的字母数字识别的相关部分,日后会继续开始人脸识别,图像分割,图像定位等等功能; 2 opencv-python安装与使用 首先我们需要安装一下环境 python3:安装python3:python教程有详细的说明,网址安装python numpy:安装numpy:pip install numpy opencv-python:安装opencv-python: pip install opencv-python 安装完opencv-python后命令行打开python交互式环境:import cv2 成功,便说明成功安装了opencv-python 2.1 imread() imread函数读取数字图像,先看一下官网对于该函数的定义 cv2.imread(path_of_image, intflag) 函数参数一: 需要读入图像的完整的路径 函数参数二: 标志以什么形式读入图像,可以选择一下方式: cv2.IMREAD_COLOR: 加载彩色图像。任何图像的透明度都将被忽略。它是默认标志 cv2.IMREAD_GRAYSCALE:以灰度模式加载图像 cv2.IMREAD_UNCHANGED:保留读取图片原有的颜色通道 1 :等同于cv2.IMREAD_COLOR 0 :等同于cv2.IMREAD_GRAYSCALE -1 :等同于cv2.IMREAD_UNCHANGED color_img = cv2.imread("image_file/1.jpeg") print(color_img.shape) gray_img=cv2.imread("image_file/1.jpeg", cv2.IMREAD_GRAYSCALE) print(gray_img.shape) #把单通道图像保存后,再读取,仍然是3通道,相当于将单通道复制到3个通道保存 cv2.imwrite("image_file/gray_1.jpeg",gray_img) 2.2 threshold() 这个函数作用是将图片二值化,图像的二值化,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果。二值化是图像分割的一种最简单的方法。二值化可以把灰度图像转换成二值图像。把大于某个临界灰度值的像素灰度设为灰度极大值,把小于这个值的像素灰度设为灰度极小值,从而实现二值化。 画图举例来说 cv.threshold()用来实现阈值分割,函数有4个参数: 参数1:要处理的原图,一般是灰度图,这也是上一步中处理的 参数2:设定的阈值 参数3:最大阈值,一般为255 参数4:阈值的方式,主要有5种,分别为:THRESH_BINARY,THRESH_BINARY_INV,THRESH_TRUNC,THRESH_TOZERO 和 THRESH_TOZERO_INV 实例如下: ret, th1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY) ret, th2 = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV) ret, th3 = cv.threshold(img, 127, 255, cv.THRESH_TRUNC) ret, th4 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO) ret, th5 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO_INV) titles = [‘Original’, ‘BINARY’, ‘BINARY_INV’, ‘TRUNC’, ‘TOZERO’, ‘TOZERO_INV’] images = [img, th1, th2, th3, th4, th5] 使用Matplotlib显示 for i in range(6): plt.subplot(2, 3, i + 1) plt.imshow(images[i], ‘gray’) plt.title(titles[i], fontsize=8) plt.xticks([]), plt.yticks([]) # 隐藏坐标轴 plt.show() 实际输出: 对应的官方中说明 2.3 morphologyEx() 形态学操作是根据图像形状进行的简单操作。一般情况下对二值化图像进行的操作。需要输入两个参数,一个是原始图像,第二个被称为结构化元素或核,它是用来决定操作的性质的。 两个基本的形态学操作是腐蚀和膨胀。他们的变体构成了开运算,闭运算,具体概念如下: 1)腐蚀: 就像土壤侵蚀一样,这个操作会把前景物体的边界腐蚀掉(但是前景仍然是白色)。这是怎么做到的呢?卷积核沿着图像滑动,如果与卷积核对应的原图像的所有像素值都是1,那么中心元素就保持原来的像素值,否则就变为零。 这会产生什么影响呢?根据卷积核的大小靠近前景的所有像素都会被腐蚀掉(变为0),所以前景物体会变小,整幅图像的白色区域会减少。这对于去除白噪声很有用,也可以用来断开两个连在一块的物体等。 2)膨胀: 与腐蚀相反,与卷积核对应的原图像的像素值中只要有一个是1,中心元素的像素值就是1。 所以这个操作会增加图像中的白色区域(前景)。一般在去噪声时先用腐蚀再用膨胀。因为腐蚀在去掉白噪声的同时,也会使前景对象变小。所以我们再对他进行膨胀。这时噪声已经被去除了,不会再回来了,但是前景还在并会增加。膨胀也可以用来连接两个分开的物体。 3)开运算: 先腐蚀,后膨胀。去除图像中小的亮点(CV_MOP_OPEN); 4)闭运算 先膨胀,后腐蚀。去除图像中小的暗点(CV_MOP_CLOSE); kernel = cv.getStructuringElement(cv.MORPH_RECT, (1, 8)) opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) cv.imshow("MORPH_OPEN_1", opening) cv2.waitKey(0) kernel = cv.getStructuringElement(cv.MORPH_RECT, (1, 8)) closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) cv.imshow("MORPH_OPEN_1", closing) cv2.waitKey(0) 3 应用案例 以上是opencv的简单使用,现在举一个实际应用的案例:识别验证码,其实按照上面3个步骤就可以将图片一步步处理,置灰,二值化,开运算,最后就可以识别了。那么首先原图如下: 1)首次处理效果,将图片灰度化,二值化,为提取轮廓做准备,二值化后,图片非黑即白两种,更有利于开闭运算处理 src = cv2.imread('image_file/before.png') gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY) ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU) cv.imshow("Binarization", binary) cv2.waitKey(0) 2)基础上面二值化图片,对结果图进行开运算处理,去除噪音部分 kernel = cv.getStructuringElement(cv.MORPH_RECT, (8, 1)) open_out = cv.morphologyEx(binl, cv.MORPH_OPEN, kernel) cv.imshow("MORPH_OPEN_2", open_out) cv2.waitKey(0) 3)最后一次处理,将背景置为白色,并且识别图片识别码 cv.bitwise_not(open_out, open_out) cv.imshow("Transform", open_out) textImage = Image.fromarray(open_out) text = pytesseract.image_to_string(textImage) cv2.waitKey(0) 4)最后打印出验证码 4 总结 相信认真一起看完上述知识点,opencv-python已经对于图像的基本操作可以熟练掌握了,接下来会对数字图像的一些其他概念进行介绍,敬请期待~ 作者:京东物流 张伟男 来源:京东云开发者社区自猿其说Tech 转载请注明来源

优秀的个人博客,低调大师

Spring Cloud 从入门到精通(一)Nacos 服务中心初探

什么是Nacos? Nacos是阿里巴巴开源的项目,是一个更易于帮助构建云原生应用的动态服务发现、配置管理和服务管理平台。英文全称 Dynamic Naming and Configuration Service,Na为naming/nameServer即注册中心,co为configuration即注册中心,service是指该注册/配置中心都是以服务为核心。 Nacos功能介绍 1、动态配置服务:动态配置服务让您能够以中心化、外部化和动态化的方式管理所有环境的配置。动态配置消除了配置变更时重新部署应用和服务的需要。配置中心化管理让实现无状态服务更简单,也让按需弹性扩展服务更容易。2、服务发现及管理:动态服务发现对以服务为中心的(例如微服务和云原生)应用架构方式非常关键。Nacos支持DNS-Based和RPC-Based(Dubbo、gRPC)模式的服务发现。Nacos也提供实时健康检查,以防止将请求发往不健康的主机或服务实例。借助Nacos,您可以更容易地为您的服务实现断路器。3、动态DNS服务:通过支持权重路由,动态DNS服务能让您轻松实现中间层负载均衡、更灵活的路由策略、流量控制以及简单数据中心内网的简单DNS解析服务。动态DNS服务还能让您更容易地实现以DNS协议为基础的服务发现,以消除耦合到厂商私有服务发现API上的风险。 为什么选择Nacos? 1、易于使用:动态配置管理、服务发现和动态的一站式解决方案;20多种开箱即用的以服务为中心的架构特性;基本符合生产要求的轻量级易用控制台。 2、更适应云架构:无缝支持Kubernetes和Spring Cloud;在主流公共云上更容易部署和运行(例如阿里云和AWS);多租户和多环境支持。 3、生产等级:脱胎于历经阿里巴巴10年生产验证的内部产品;支持具有数百万服务的大规模场景;具备企业级SLA的开源产品。 4、丰富的应用场景:支持限流、大促销预案和异地多活;直接支持或稍作扩展即可支持大量有用的互联网应用场景;流量调度和服务治理。 准备环境 在开始之前,请安装以下组件(官方推荐): 64位操作系统:支持Linux/Unix/Mac/Windows,建议使用Linux/Unix/Mac(本次演示在Windows系统)。 64位JDK 1.8版本及以上。 Maven 3.2.x版本及以上。 下载源码或者安装包 Nacos可以通过源码或者发行包两种方式下载。 1)从Github下载源代码 git clone https:``//github.com/alibaba/nacos.git``cd nacos/``mvn -Prelease-nacos -Dmaven.test.skip=``true clean install -U ``ls -al distribution/target/`` // change the $version to your actual path``cd distribution/target/nacos-server-$version/nacos/bin 2)下载编译后压缩包方式 https://github.com/alibaba/nacos/releases 建议选择稳定版本(将$version替换成版本号): unzip nacos-server-$version.zip OR tar -xvf nacos-server-$version.tar.gz``cd nacos/bin Windows版本直接使用解压工具即可。 启动Nacos Server服务 Linux/Unix/Mac操作系统,执行命令如下: sh startup.sh -m standalone 如果使用的是ubuntu系统,或遇到此错误消息(找不到符号),请尝试方式运行: bash startup.sh -m standalone Windows 操作系统,执行命令如下: cmd startup.cmd 服务与配置管理nacos server访问地址:http://127.0.0.1:8848/nacos/nacos默认账户密码:nacos/nacos 1、服务注册在控制台中手动添加配置信息如下: curl -X POST "http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=blog.yoodb.com&ip=123.57.47.154&port=443" 参考如图所示: 参数含义 服务名:blog.yoodb.com 保护阈值:0 分组(默认):DEFAULT_GROUP 2、服务发现参考服务注册此步跳过 curl -X GET "http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=blog.yoodb.com" 3、发布配置 在命令行执行如下命令,向Nacos Server中添加一条配置,也可在控制台中手动添加。 curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=blog.yoodb.com&group=TEXT_GROUP&content=helloWorld" 参考如图所示: 参数含义 dataId:blog.yoodb.com group:TEXT_GROUP 配置内容:helloWorld 4、获取配置参考发布配置此步跳过。 curl -X GET "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=blog.yoodb.com&group=TEXT_GROUP"

优秀的个人博客,低调大师

那怎么入门Netty

本文是Netty系列笔记第2篇 Netty是网络应用框架,所以从最本质的角度来看,是对网络I/O模型的封装使用。 因此,要深刻理解Netty的高性能,也必须从网络I/O模型说起。 看完本文,可以回答这三个问题: 五种I/O模型是什么?核心区别在哪里? 同步=阻塞?异步=非阻塞? Netty的高性能,是采用了哪种I/O模型? 1.掌握五种I/O模型的关键钥匙 Unix系统下的五种基本I/O模型大家应该都有所耳闻,分为: blocking I/O(同步阻塞IO,BIO) nonblocking I/O(同步非阻塞IO,NIO) I/O multiplexing (I/O多路复用) signal driven I/O(信号驱动I/O) asynchronous I/O(异步I/O,AIO) 每种I/O的特性如何,尤其是同步/非同步、阻塞/非阻塞的区别,其实很多人并不能准确地进行区分。 所以,我们先把最核心的“钥匙”告诉大家,带着这把“钥匙”再来看I/O模型的关键问题,就能手到擒来了。 当一次网络IO发生时,主要涉及到三个对象: 发起此次IO操作的Process或者Application 系统内核kernel。用户进程无法直接操作I/O设备,必须通过系统内核kernel与I/O设备交互。 I/O设备,包括网络、磁盘等。本文主要针对网络。 真正的I/O过程,主要分为两个阶段: 等待数据准备阶段。 数据拷贝阶段。数据准备完毕,从内核kernel拷贝到进程process中 以一个socket上的输入操作为例。 第一步通常涉及等待数据从网络中到达。当所等待分组到达时,它被复制到内核中的某个缓冲区。 第二步就是把数据从内核缓冲区复制到用户态缓冲区。 这里,我们先记住这两个阶段,掌握所有I/O模型区别的“关键钥匙”就在它们身上。 2.五种I/O模型详解 2.1 同步阻塞I/O, BIO 我们一般使用最多的,最基础的I/O模型就是同步阻塞I/O。 典型应用:阻塞socket、Java BIO 我们来解读一下BIO的过程: 应用进程向内核发起 I/O 请求,发起调用的线程一直阻塞,等待内核返回结果。 数据准备完毕,从内核kernel拷贝到用户态内存(仍旧阻塞),然后kernel返回结果,用户进程process结束阻塞,重新运行。 “关键钥匙”分析:BIO的特点就是在IO执行的两个阶段都被阻塞了。 所以,我们日常使用BIO模型的时候,提高性能的方式,就是采用多线程。 在一般的场景中,多线程模型下的BIO是成本较低、收益较高的方式。但是,如果在高并发的场景下,过多的创建线程,会严重占据系统资源,降低系统对外界响应效率。 那是不是可以考虑使用“线程池”或者“连接池”呢? 一定程度上可以。“池化”的目的在于减少创建和销毁线程的频率,让空闲的线程重新承担新的执行任务,维持一个合理的线程数量,可以很好的降低系统开销。 但是,“池化”技术只能一定程度上缓解了频繁调用IO接口带来的资源占用。如果“池”上限100,而我们需要1000的IO,那并不能解决性能问题,这是由于BIO模型本身的限制决定的。 所以,需要非阻塞I/O来尝试解决这个问题。 2.2 同步非阻塞I/O, NIO BIO的阻塞问题,让我们考虑使用非阻塞的NIO模型。 典型应用:socket的非阻塞模式 应用进程向内核发起 I/O 请求后,如果kernel中的数据还没有准备好,不再会“阻塞”等待结果,而是会立即返回。 从用户进程角度讲 ,它发起一个IO操作后,并不需要等待,而是马上就得到了一个结果。 用户进程判断结果是一个error时,它就知道数据还没有准备好,于是它开始发起轮训操作。 直到kernel中的数据准备好了,一旦用户再轮训过来,就马上将数据拷贝到了用户内存,然后返回。 所以,在非阻塞式IO中,用户进程其实是需要不断地主动询问kernel数据准备好了没有。 “关键钥匙”分析: 非阻塞NIO模型相比于BIO的显著差异在于,在“数据等待”阶段,不再“阻塞”,立即返回。 但是在“数据拷贝”阶段,仍然是“阻塞”的。 虽然非阻塞模型避免了“数据等待”阶段的阻塞,但是,采用轮询方式,会导致系统上下文切换开销很大,会大幅度推高CPU 占用率。 因此,单独使用非阻塞 I/O 模型的效率并不高。而且随着并发量的提升,非阻塞 I/O 会存在严重的性能浪费。 我们可以看到,轮训的目的只是检测“数据是否已经就绪”,而操作系统提供了更为高效的检测接口, 例如select()多路复用模式,可以一次检测多个连接是否活跃。 2.3 多路复用IO 多路复用实现了一个线程处理多个 I/O 句柄的操作,有些地方也称这种IO方式为事件驱动IO(event driven IO)。 多路 指的是多个数据通道 复用 指的是使用一个或多个固定线程来处理每一个 Socket。 典型应用:select、poll、epoll三种方案Java NIO 多个的进程的IO可以注册到一个复用器(selector)上,然后用一个进程调用select,select会监听所有注册进来的IO。 如果selector所有监听的IO在内核缓冲区都没有可读数据,select调用进程会被阻塞;同时,kernel会“监视”所有select负责的socket,如果任何一个socket中的数据准备好了,select就会返回; 然后select调用进程可以自己或通知另外的进程(注册进程)来再次发起读取IO,然后process将数据从kernel拷贝到用户进程,读取内核中准备好的数据。 可以看到,多个进程注册IO后,只有一个select调用进程被阻塞。 多路复用解决了同步阻塞 I/O 和同步非阻塞 I/O 的问题,是一种非常高效的 I/O 模型。我们可以直观看到,这个模型的好处在于单个process就可以同时处理多个网络连接的IO。 “关键钥匙”分析: 多路复用I/O,select阶段,对于多路socket的“数据等待”阶段而言,是“非阻塞”。 对单个socket的“数据拷贝”阶段,也是“阻塞”。 这里需要特别注意!!!! 其实如果处理的IO数不多的情况下,使用多路复用IO的web server不一定比使用 池化+BIO 的web server性能更好,可能延迟还更大。考虑极端情况下,只有一个IO,多路复用需要 2 次系统调用(select + recvfrom),而BIO只需要 1 次系统调用(recvfrom)。 所以,多路复用IO的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。 2.4 信号驱动I/O 在使用信号驱动 I/O 时,当数据准备就绪后,内核通过发送一个 SIGIO 信号通知应用进程,应用进程就可以开始读取数据了。 信号驱动I/O模型的最大特点,就是不需要process进程不断轮训内核是否已经准备就绪。 “关键钥匙”分析: 信号驱动I/O在"数据等待"阶段“非阻塞”。 当数据准备完成后,信号通知process,process开始“数据拷贝”阶段,这里仍然是“阻塞”的。 信号驱动 I/O 有几个缺陷:1)在大量 IO 操作时可能会因为信号队列溢出导致没法通知。 2)信号驱动 I/O 尽管对于处理 UDP 套接字来说有用,信号通知意味着到达一个数据报,或者返回一个异步错误。但是,对于 TCP 而言,信号驱动的 I/O 方式不太好用。因为导致信号通知的情况有非常多种,每一个来进行判别会消耗很大资源。 所以信号驱动I/O模式用得非常少。 而且尤其需要注意,在“数据拷贝”阶段,它仍然是“阻塞”的。 2.5 异步I/O,AIO 真正的异步I/O,就是AIO。 典型应用:JAVA7 AIO、高性能服务器 根据前面四个模型的分析,相信大家已经能明显看懂这个模型的运行方式了。 用户进程发起I/O请求后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它收到一个请求之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它I/O操作完成了。 AIO最重要的一点是从内核缓冲区拷贝数据到用户态缓冲区的过程也是由系统异步完成,应用进程只需要在指定的数组中引用数据即可。 AIO 与信号驱动 I/O 的主要区别:信号驱动 I/O 由内核通知何时可以开始一个 I/O 操作,而异步 I/O 由内核通知 I/O 操作何时已经完成。 “关键钥匙”分析: "数据等待"阶段,非阻塞 "数据拷贝”阶段,非阻塞 AIO是真正的异步模型,它不会对请求进程产生任何的阻塞。 3. 同步=阻塞?异步=非阻塞? 日常使用过程中,我们往往把 同步I/O 等同于 阻塞I/O,异步I/O 等同于 非阻塞I/O。实际上,严格意义来说,这两组概念还是有很大的区别的。 3.1 阻塞I/O 与 非阻塞I/O 阻塞与非阻塞的区别比较明显,也很好理解。 结合I/O模型来说,阻塞I/O会一直block对应的进程直到操作完成,而非阻塞 IO在kernel 在"等待数据准备"阶段会立刻返回。 所以我们一般认为,阻塞I/O只有BIO,另外四个模型都是属于非阻塞I/O。 3.2 同步I/O 与 异步I/O 先来看看 同步I/O 和 异步I/O 的定义是什么,根据POSIX的定义: 同步I/O : A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes; 异步I/O : An asynchronous I/O operation does not cause the requesting process to be blocked; 两者的区别就在于同步I/O做 "IO operation”的时候会将process阻塞。 那么按照这个定义,我们看看前面每个模型的“关键钥匙”分析部分,可以明显看到,BIO,NIO,IO多路复用、信号驱动IO 四种模型都属于 同步IO。 因为它们在IO的第二阶段,真正执行“数据拷贝”的阶段,都是“阻塞”的。以NIO为例,在执行recvfrom这个系统调用的时候,如果kernel的数据没有准备好,这时候不会block进程。但是当kernel中数据准备好的时候,recvfrom会将数据从kernel拷贝到用户内存中,这个时候进程是被block了。 同理,信号驱动IO,当内核中IO数据就绪时以SIGIO信号通知请求进程,请求进程再把数据从内核读入到用户空间,这一步也是阻塞的。 所以,真正的异步I/O只有一个,就是AIO。当进程发起IO操作之后,就直接返回再也不管了,直到kernel发送一个信号,告诉进程说IO完成。在这整个过程中,进程完全没有被阻塞。如定义所说,不会因为IO操作阻塞。 4. Netty采用了哪种I/O模型呢? Netty 的 I/O 模型是基于非阻塞 I/O 实现的,底层依赖的是 JDK NIO 框架的多路复用器 Selector。 一个多路复用器 Selector 可以同时轮询多个 Channel,采用 epoll 模式后,只需要一个线程负责 Selector 的轮询,就可以接入成千上万的客户端。 更具体的实现方式和模型,我们下一期再展开说明。 对了,一定有同学想问,Netty为什么不采用AIO呢? 因为 AIO 的目的是希望 I/O 线程不阻塞主线程,属于异步 I/O,由内核通知 I/O 操作何时完成。AIO 适用于连接数多的且需要长时间连接的场景。 对于AIO来说,目前操作系统支持程度有限且实现起来复杂。 Netty也尝试过AIO,但是效果不是很理想,最终废弃了。 参考书目:《UNIX Network Programming(Volume1,3rd)》 如果有任何疑问或者建议,欢迎写留言或者微信和我联系哦~ 往期热门笔记合集推荐: HBase原理与实战笔记合集 MySQL实战笔记合集 Canal/Otter源码与实战笔记合集 Java实战技巧笔记合集 原创:阿丸笔记(微信公众号:aone_note),欢迎分享,转载请保留出处。 扫描下方二维码可以关注我哦~ 觉得不错,就点个 再看吧👇 本文分享自微信公众号 - 阿丸笔记(aone_note)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

优秀的个人博客,低调大师

阿里云ECS服务器入门使用步骤 小白必看教程

一、阿里云根据个人需要选合适的云服务器,选好cpu、内存、带宽,地域,这四个是主要的。其他可以默认选择。 二、登陆控制台 输入账号密码,进去看到服务界面,新手可能不容易看懂。点击左侧菜单,点击云服务器,显示界面如图: 点击实例,在左上角选择区域(一定要选对地域才能看到服务器),这时看到服务器信息了,如图: 大家不要看这里这么多信息,对我们有用的其实只有几个而已,别的都不用看。 更多参阅云服务器配置帮助文档。 三、连接主机 1、通过控制台连接 阿里云服务器要用到两个密码,一个是远程登录密码,一个是实例密码,就是我们平常登录服务器的root密码(以linux服务器为例)。 通过控制台连接服务器需要使用到这两个密码,如果不知道重置即可。 注意:修改实例密码需要重启服务器才能生效。 点击远程连接,输入远程连接密码 输入root用户和密码(就是刚才改过的实例密码),开始对服务器进行操作。 登录成功后,可以输入各种命令。 点击左侧按钮列表的断开连接,就能够断开与服务器的链接了。 2、通过工具连接 在云控制台的实例页面看到公网IP,通过工具软件连接服务器,和上面的作用一样,可以输入各种命令了。 三、开通安全组 同样在实例最右侧点击【更多】>>【网络和安全组】>>【安全组配置】 点击配置规则 入方向看到的就是目前服务器的安全组规则了,你可以在这里添加、修改、删除规则。 比如要开放 80端口,按照下面的例子填写。 这块挺重要的,规则添加不对了可能就无法正常访问了。 更多参阅安全组帮助文档。 四、网站搭建 做网站的话可以搭配系统镜像使用,阿里云自带一键开通,方法如下图: 点击【确定,更换系统盘】,注意提前保存数据。 点击【镜像市场】,从镜像市场选择 搜索【宝塔面板】,选择0/月的,注意看已使用人数,选择人数多的那个。 自定义密码,然后输入符合要求的密码。这里记住登陆名和密码,以后链接服务器都要用。 也可以用密钥方式,这里不细说了。 接下来记住宝塔面板的登陆地址,账号密码。 去登陆到宝塔面板中,开始建站之旅。 记住如果宝塔面板无法登陆,那是因为安全组中没有添加面板的端口,按照上面的办法去添加就行了。 更多参阅镜像市场帮助文档。 我也是从新手小白一路跌跌撞撞走过来的,所以总结了不少相关经验和教程,希望能帮助你。关于ECS云服务器选购和基本使用的经验,所以来总结一下: 关于几个要点总结如下: 如何购买阿里云服务器参考教程:阿里云服务器购买图文教程 如何需要免备案的云服务器请参考文章:阿里云香港与海外云服务器购买教程 域名和网站是否备案问题科普教程:域名一定需要备案吗?什么情况下域名不用备案? 如何远程连接阿里云(Linux)服务器参考教程:使用Xshell和Xftp远程连接阿里云Linux服务器 如何远程连接阿里云(Window)服务器参考教程:如何远程连接登录阿里云Window服务器 关于如何选择操作系统参考教程:如何选择操作系统图文教程(选Linux还是Windows?) 如何重置云服务器登录密码参考教程:教你如何重置阿里云Linux远程连接登录密码 如何设置安全组规则(端口放行)参考教程:阿里云安全组端口设置完整图文教程 如何你想在服务器上安装宝塔面板参考教程:阿里云服务器安装宝塔面板图文教程 如何你想在服务器上安装WordPress网站参考教程:阿里云服务器安装WordPress网站完整图文教程 更多参考地址: 阿里云官方(新用户需官网注册查看) 阿里云域名注册地址:阿里云万网域名注册中心 阿里云服务器1折秒杀:阿里云服务器1折秒杀官网地址

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册