K8S系列一:概念入门

写在前面

本文组织方式:

  1. K8S的架构、作用和目的。需要首先对K8S整体有所了解。
    1. K8S是什么?
    2. 为什么是K8S?
    3. K8S怎么做?
  2. K8S的重要概念,即K8S的API对象。要学习和使用K8S必须知道和掌握的几个对象。
    1. Pod 实例
    2. Volume 数据卷
    3. Container 容器
    4. Deployment 和 ReplicaSet
    5. Service,Ingress和Istio
    6. namespace 命名空间
    7. 其他

I. K8S概览

1.1 K8S是什么?

K8S是Kubernetes的全称,官方称其是:

Kubernetes is an open source system for managing containerized applications across multiple hosts. It provides basic mechanisms for deployment, maintenance, and scaling of applications.
用于自动部署、扩展和管理“容器化(containerized)应用程序”的开源系统。

翻译成大白话就是:“K8S是负责自动化运维管理多个Docker程序的集群”。那么问题来了:Docker运行可方便了,为什么要用K8S,它有什么优势?

插一句题外话:

  • 为什么Kubernetes要叫Kubernetes呢?维基百科已经交代了(老美对星际是真的痴迷):
    Kubernetes(在希腊语意为“舵手”或“驾驶员”)由Joe Beda、Brendan Burns和Craig McLuckie创立,并由其他谷歌工程师,包括Brian Grant和Tim Hockin等进行加盟创作,并由谷歌在2014年首次对外宣布 。该系统的开发和设计都深受谷歌的Borg系统的影响,其许多顶级贡献者之前也是Borg系统的开发者。在谷歌内部,Kubernetes的原始代号曾经是Seven,即星际迷航中的Borg(博格人)。Kubernetes标识中舵轮有七个轮辐就是对该项目代号的致意。
  • 为什么Kubernetes的缩写是K8S呢?我个人赞同Why Kubernetes is Abbreviated k8s中说的观点“嘛,写全称也太累了吧,不如整个缩写”。其实只保留首位字符,用具体数字来替代省略的字符个数的做法,还是比较常见的。

1.2 为什么是K8S?

试想下传统的后端部署办法:把程序包(包括可执行二进制文件、配置文件等)放到服务器上,接着运行启动脚本把程序跑起来,同时启动守护脚本定期检查程序运行状态、必要的话重新拉起程序。

有问题吗?显然有!最大的一个问题在于:如果服务的请求量上来,已部署的服务响应不过来怎么办?传统的做法往往是,如果请求量、内存、CPU超过阈值做了告警,运维马上再加几台服务器,部署好服务之后,接入负载均衡来分担已有服务的压力。

问题出现了:从监控告警到部署服务,中间需要人力介入!那么,有没有办法自动完成服务的部署、更新、卸载和扩容、缩容呢?

这,就是K8S要做的事情:自动化运维管理Docker(容器化)程序

1.3 K8S怎么做?

我们已经知道了K8S的核心功能:自动化运维管理多个容器化程序。那么K8S怎么做到的呢?这里,我们从宏观架构上来学习K8S的设计思想。首先看下图,图片来自文章Kubernetes Components(笔者以为这张官方的组件图比架构图更清晰准确):

<img src="https://pic2.zhimg.com/v2-2af5a64fc28a91f57bde91dac0eba00d_b.jpg" data-size="normal" data-rawwidth="1425" data-rawheight="636" class="origin_image zh-lightbox-thumb" width="1425" data-original="https://pic2.zhimg.com/v2-2af5a64fc28a91f57bde91dac0eba00d_r.jpg"/>

k8s components

K8S是属于主从设备模型(Master-Slave架构),即有Master节点负责核心的调度、管理和运维,Slave节点则在执行用户的程序。但是在K8S中,主节点一般被称为Master Node或者Head Node(本文采用Master Node称呼方式),而从节点则被称为Worker Node或者Node(本文采用Worker Node称呼方式)。

要注意一点:Master Node和Worker Node是分别安装了K8S的Master和Woker组件的实体服务器,每个Node都对应了一台实体服务器(虽然Master Node可以和其中一个Worker Node安装在同一台服务器,但是建议Master Node单独部署),所有Master Node和Worker Node组成了K8S集群,同一个集群可能存在多个Master Node和Worker Node。

首先来看Master Node都有哪些组件:

  • API ServerK8S的请求入口服务。API Server负责接收K8S所有请求(来自UI界面或者CLI命令行工具),然后,API Server根据用户的具体请求,去通知其他组件干活。从图中可以知道,API Server实际可以部署多个实例,以增大请求吞吐。
  • SchedulerK8S中的调度服务。当用户要部署服务时,Scheduler会选择最合适的Worker Node(服务器)来部署。从上图可以知道,Scheduler也可以部署多个实例,以增大处理能力。
  • Controller ManagerK8S的控制服务。Controller Manager本身就是总称,实际上有很多具体的Controller,在文章Components of Kubernetes Architecture中提到的有Node Controller、Service Controller、Volume Controller等,分别负责不同K8S对象。举个例子,比如用户要求A服务部署2个副本,那么当其中一个服务挂了的时候,Controller会马上调整,让Scheduler再选择一个Worker Node重新部署服务。
  • etcdK8S的存储服务。etcd存储了K8S的关键配置和用户配置,K8S中仅API Server才具备读写权限,其他组件必须通过API Server的接口才能读写数据(见Kubernetes Works Like an Operating System)。

接着来看Worker Node的组件,笔者更赞同HOW DO APPLICATIONS RUN ON KUBERNETES文章中提到的组件介绍:

  • KubeletWorker Node的监视器,以及与Master Node的通讯器。Kubelet是Master Node安插在Worker Node上的“眼线”,它会定期向Master Node汇报自己Node上运行的服务的状态,并接受来自Master Node的命令,并执行。
  • Kube-ProxyK8S的网络代理。私以为称呼为Network-Proxy可能更适合?Kube-Proxy负责Node在K8S的网络通讯、以及对外部网络流量的负载均衡。
  • Container RuntimeWorker Node的运行环境。即安装了容器化所需的软件环境确保容器化程序能够跑起来,比如Docker Engine。大白话就是帮忙装好了Docker运行环境。
  • Logging LayerK8S的监控状态收集器。私以为称呼为Monitor可能更合适?Logging Layer负责采集Node上所有服务的CPU、内存、磁盘、网络等监控项信息。
  • Add-OnsK8S管理运维Worker Node的插件组件。有些文章认为Worker Node只有三大组件,不包含Add-On,但笔者认为K8S系统提供了Add-On机制,让用户可以扩展更多定制化功能,是很不错的亮点。

总结来看,K8S的Master Node具备:请求入口管理(API Server),Worker Node调度(Scheduler),监控和自动调节(Controller Manager),以及存储功能(etcd);而K8S的Worker Node具备:状态和监控收集(Kubelet),网络和负载均衡(Kube-Proxy)、保障容器化运行环境(Container Runtime)、以及定制化功能(Add-Ons)。

到这里,相信你已经对K8S究竟是做什么的,有了大概认识。接下来,再来认识下K8S的Deployment、Pod、Replica Set、Service等,但凡谈到K8S,就绕不开这些名词,而这些名词也是最让K8S新手们感到头疼、困惑的。


II. K8S重要概念

2.1 Pod实例

官方对于Pod的解释是:

Pod是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。

这样的解释还是很难让人明白究竟Pod是什么,但是对于K8S而言,Pod可以说是所有对象中最重要的概念了!因此,我们必须首先清楚地知道“Pod是什么”,再去了解其他的对象。

从官方给出的定义,联想下“最小的xxx单元”,是不是可以想到本科在学校里学习“进程”的时候,教科书上有一段类似的描述:资源分配的最小单位;还有”线程“的描述是:CPU调度的最小单位。什么意思呢?”最小xx单位“要么就是事物的衡量标准单位,要么就是资源的闭包、集合。前者比如长度米、时间秒;后者比如一个”进程“是存储和计算的闭包,一个”线程“是CPU资源(包括寄存器、ALU等)的闭包。

同样的,Pod就是K8S中一个服务的闭包。这么说的好像还是有点玄乎,更加云里雾里了。简单来说,Pod可以被理解成一群可以共享网络、存储和计算资源的容器化服务的集合。再打个形象的比喻,在同一个Pod里的几个Docker服务/程序,好像被部署在同一台机器上,可以通过localhost互相访问,并且可以共用Pod里的存储资源(这里是指Docker可以挂载Pod内的数据卷,数据卷的概念,后文会详细讲述,暂时理解为“需要手动mount的磁盘”)。笔者总结Pod如下图,可以看到:同一个Pod之间的Container可以通过localhost互相访问,并且可以挂载Pod内所有的数据卷;但是不同的Pod之间的Container不能用localhost访问,也不能挂载其他Pod的数据卷

<img src="https://pic1.zhimg.com/v2-ceb8fc9f98f4ce1f83f9962edc2bd804_b.jpg" data-size="normal" data-rawwidth="1279" data-rawheight="619" class="origin_image zh-lightbox-thumb" width="1279" data-original="https://pic1.zhimg.com/v2-ceb8fc9f98f4ce1f83f9962edc2bd804_r.jpg"/>

K8S Pod示意图

对Pod有直观的认识之后,接着来看K8S中Pod究竟长什么样子,具体包括哪些资源?

K8S中所有的对象都通过yaml来表示,笔者从官方网站摘录了一个最简单的Pod的yaml:

apiVersion:v1kind:Podmetadata:name:memory-demonamespace:mem-examplespec:containers:- name:memory-demo-ctrimage:polinux/stressresources:limits:memory:"200Mi"requests:memory:"100Mi"command:["stress"]args:["--vm","1","--vm-bytes","150M","--vm-hang","1"]volumeMounts:- name:redis-storagemountPath:/data/redisvolumes:- name:redis-storageemptyDir:{}

看不懂不必慌张,且耐心听下面的解释:

  • apiVersion记录K8S的API Server版本,现在看到的都是v1,用户不用管。
  • kind记录该yaml的对象,比如这是一份Pod的yaml配置文件,那么值内容就是Pod
  • metadata记录了Pod自身的元数据,比如这个Pod的名字、这个Pod属于哪个namespace(命名空间的概念,后文会详述,暂时理解为“同一个命名空间内的对象互相可见”)。
  • spec记录了Pod内部所有的资源的详细信息,看懂这个很重要:
    • containers记录了Pod内的容器信息,containers包括了:name容器名,image容器的镜像地址,resources容器需要的CPU、内存、GPU等资源,command容器的入口命令,args容器的入口参数,volumeMounts容器要挂载的Pod数据卷等。可以看到,上述这些信息都是启动容器的必要和必需的信息
    • volumes记录了Pod内的数据卷信息,后文会详细介绍Pod的数据卷。

2.2 Volume 数据卷

K8S支持很多类型的volume数据卷挂载,具体请参见K8S卷。前文就“如何理解volume”提到:“需要手动mount的磁盘”,此外,有一点可以帮助理解:数据卷volume是Pod内部的磁盘资源

其实,单单就Volume来说,不难理解。但是上面还看到了volumeMounts,这俩是什么关系呢?

volume是K8S的对象,对应一个实体的数据卷;而volumeMounts只是container的挂载点,对应container的其中一个参数。但是,volumeMounts依赖于volume,只有当Pod内有volume资源的时候,该Pod内部的container才可能有volumeMounts。

2.3 Container 容器

本文中提到的镜像Image、容器Container,都指代了Pod下的一个container。关于K8S中的容器,在2.1Pod章节都已经交代了,这里无非再啰嗦一句:一个Pod内可以有多个容器container

在Pod中,容器也有分类,对这个感兴趣的同学欢迎自行阅读更多资料:

  • 标准容器 Application Container
  • 初始化容器 Init Container
  • 边车容器 Sidecar Container
  • 临时容器 Ephemeral Container

一般来说,我们部署的大多是标准容器( Application Container)

2.4 Deployment 和 ReplicaSet(简称RS)

除了Pod之外,K8S中最常听到的另一个对象就是Deployment了。那么,什么是Deployment呢?官方给出了一个要命的解释:

一个 Deployment 控制器为 PodsReplicaSets 提供声明式的更新能力。
你负责描述 Deployment 中的 目标状态,而 Deployment 控制器以受控速率更改实际状态, 使其变为期望状态。你可以定义 Deployment 以创建新的 ReplicaSet,或删除现有 Deployment,并通过新的 Deployment 收养其资源。

翻译一下:Deployment的作用是管理和控制Pod和ReplicaSet,管控它们运行在用户期望的状态中。哎,打个形象的比喻,Deployment就是包工头,主要负责监督底下的工人Pod干活,确保每时每刻有用户要求数量的Pod在工作。如果一旦发现某个工人Pod不行了,就赶紧新拉一个Pod过来替换它。

新的问题又来了:那什么是ReplicaSets呢?

ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。

再来翻译下:ReplicaSet的作用就是管理和控制Pod,管控他们好好干活。但是,ReplicaSet受控于Deployment。形象来说,ReplicaSet就是总包工头手下的小包工头

笔者总结得到下面这幅图,希望能帮助理解:

<img src="https://pic1.zhimg.com/v2-f989cacf78c353508ed700789d1b0884_b.jpg" data-size="normal" data-rawwidth="1444" data-rawheight="705" class="origin_image zh-lightbox-thumb" width="1444" data-original="https://pic1.zhimg.com/v2-f989cacf78c353508ed700789d1b0884_r.jpg"/>

K8S Deployment、ReplicaSet和Pod关系图

新的问题又来了:如果都是为了管控Pod好好干活,为什么要设置Deployment和ReplicaSet两个层级呢,直接让Deployment来管理不可以吗?

引入这样子的层级管理制度是为了实现前后两个版本平滑升级、平滑回滚等高级功能。笔者画了一副Deployment平滑升级(其中一种策略,实际可选有很多策略,本文不展开),或许可以帮助理解。如下:

<img src="https://pic3.zhimg.com/v2-c0c3aeb93fc765c496b97dd1070e6caa_b.jpg" data-size="normal" data-rawwidth="1590" data-rawheight="430" class="origin_image zh-lightbox-thumb" width="1590" data-original="https://pic3.zhimg.com/v2-c0c3aeb93fc765c496b97dd1070e6caa_r.jpg"/>

Deployment 升级

因此,才会看到许多地方建议K8S用户,使用Deployment来部署服务,而不要直接用ReplicaSet。当Deployment被部署的时候,K8S会自动生成要求的ReplicaSet和Pod。在K8S官方文档中也指出用户只需要关心Deployment而不操心ReplicaSet:

This actually means that you may never need to manipulate ReplicaSet objects: use a Deployment instead, and define your application in the spec section.
这实际上意味着您可能永远不需要操作ReplicaSet对象:直接使用Deployments并在规范部分定义应用程序。

补充说明:在K8S中还有一个对象 --- ReplicationController(简称RC)官方文档对它的定义是:

ReplicationController 确保在任何时候都有特定数量的 Pod 副本处于运行状态。 换句话说,ReplicationController 确保一个 Pod 或一组同类的 Pod 总是可用的。

怎么样,和ReplicaSet是不是很相近?在Deployments, ReplicaSets, and pods教程中说“ReplicationController是ReplicaSet的前身”,官方也推荐用Deployment取代ReplicationController来部署服务。

2.5 Service,Ingress和Istio

吐槽下K8S的概念/对象/资源是真的多啊!前文介绍的Deployment、ReplicationController和ReplicaSet主要管控Pod程序服务;那么,Service和Ingress则负责管控Pod网络服务

我们先来看看官方文档中Service的定义:

将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。
使用 Kubernetes,您无需修改应用程序即可使用不熟悉的服务发现机制。 Kubernetes 为 Pods 提供自己的 IP 地址,并为一组 Pod 提供相同的 DNS 名, 并且可以在它们之间进行负载均衡。

翻译下:K8S中的服务(Service)并不是我们常说的“服务”的含义,而更像是网关层,是若干个Pod的流量入口、流量均衡器。

那么,为什么要Service呢

私以为在这一点上,官方文档讲解地非常清楚:

Kubernetes Pod 是有生命周期的。 它们可以被创建,而且销毁之后不会再启动。 如果您使用 Deployment 来运行您的应用程序,则它可以动态创建和销毁 Pod。
每个 Pod 都有自己的 IP 地址,但是在 Deployment 中,在同一时刻运行的 Pod 集合可能与稍后运行该应用程序的 Pod 集合不同。
这导致了一个问题: 如果一组 Pod(称为“后端”)为群集内的其他 Pod(称为“前端”)提供功能, 那么前端如何找出并跟踪要连接的 IP 地址,以便前端可以使用工作量的后端部分?

补充说明:K8S集群的网络管理和拓扑也有特别的设计,以后会专门出一章节来详细介绍K8S中的网络。这里需要清楚一点:K8S集群内的每一个Pod都有自己的IP(是不是很类似一个Pod就是一台服务器,然而事实上是多个Pod存在于一台服务器上,只不过是K8S做了网络隔离),在K8S集群内部还有DNS等网络服务(一个K8S集群就如同管理了多区域的服务器,可以做复杂的网络拓扑)。

此外,笔者推荐k8s外网如何访问业务应用对于Service的介绍,不过对于新手而言,推荐阅读前半部分对于service的介绍即可,后半部分就太复杂了。我这里做了简单的总结:

Service是K8S服务的核心,屏蔽了服务细节,统一对外暴露服务接口,真正做到了“微服务”。举个例子,我们的一个服务A,部署了3个备份,也就是3个Pod;对于用户来说,只需要关注一个Service的入口就可以,而不需要操心究竟应该请求哪一个Pod。优势非常明显:一方面外部用户不需要感知因为Pod上服务的意外崩溃、K8S重新拉起Pod而造成的IP变更,外部用户也不需要感知因升级、变更服务带来的Pod替换而造成的IP变化,另一方面,Service还可以做流量负载均衡

K8S的Service有3种类型(最新出了一种新的ClusterName,可以直接提供DNS Name),总结如下:

  • ClusterIP:只能提供K8S集群内可以访问的IP和Port。
  • NodePort:在上面的基础上,提供K8S集群外部可以访问的Port,IP则是集群内任意一个NodeIP。
  • LoadBlancer:在上面的基础上,提供K8S集群外可以访问的IP和Port。需要注意的是,在LoadBlancer中可以设置关闭NodePort。还有一点需要注意,LoadBlanacer依赖集群底座的能力,并不是所有的K8S都能使用LoadBlancer。

因此,我们可以看到,Service实际上已经能够满足基础通讯要求,包括K8S集群内部和内外。那么,还需要Ingress和Istio吗?

官方文档中的对Ingress解释是:

Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。 Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。

翻译一下:Ingress是整个K8S集群的接入层,复杂集群内外通讯。

这里对于Ingress和Istio不做深入介绍,感兴趣的读者欢迎关注后续文章。Ingress是官方团队推出的K8S集群接入层,Istio则是社区开发和运维的适配K8S的接入层组件。在实际项目中,我们往往需要功能更为复杂的网关层,比如流量转发,熔断等。而Service提供的功能太过简单,流量只能导入到单点或者有限服务上,无法满足实际生产需求,因此Ingress和Istio应运而生。其中,Istio又发展最好,功能和生态最丰富,是目前主流采用的网关组件。

最后,笔者把Ingress/Istio和Service的关系绘制网络拓扑关系图如下,希望对理解这两个概念有所帮助:

<img src="https://pic4.zhimg.com/v2-5f199950c6a1a5cbeb5d098b5d3bd357_b.jpg" data-size="normal" data-rawwidth="1298" data-rawheight="873" class="origin_image zh-lightbox-thumb" width="1298" data-original="https://pic4.zhimg.com/v2-5f199950c6a1a5cbeb5d098b5d3bd357_r.jpg"/>

K8S Ingress、Service和Pod关系图

2.6 namespace 命名空间

和前文介绍的所有的概念都不一样,namespace跟Pod没有直接关系,而是K8S另一个维度的对象。或者说,前文提到的概念都是为了服务Pod的,而namespace则是为了服务整个K8S集群的。

那么,namespace是什么呢?

官方文档定义:

Kubernetes 支持多个虚拟集群,它们底层依赖于同一个物理集群。 这些虚拟集群被称为名字空间。

翻译一下:namespace是为了把一个K8S集群划分为若干个资源不可共享的虚拟集群而诞生的

也就是说,可以通过在K8S集群内创建namespace来分隔资源和对象。比如我有2个业务A和B,那么我可以创建ns-a和ns-b分别部署业务A和B的服务,如在ns-a中部署了一个deployment,名字是hello,返回用户的是“hello a”;在ns-b中也部署了一个deployment,名字恰巧也是hello,返回用户的是“hello b”(要知道,在同一个namespace下deployment不能同名;但是不同namespace之间没有影响)。前文提到的所有对象,都是在namespace下的;当然,也有一些对象是不隶属于namespace的,而是在K8S集群内全局可见的,官方文档提到的可以通过命令来查看,具体命令的使用办法,笔者会出后续的实战文章来介绍,先贴下命令:

# 位于名字空间中的资源
kubectl api-resources --namespaced=true

# 不在名字空间中的资源
kubectl api-resources --namespaced=false

不在namespace下的对象有:

<img src="https://pic2.zhimg.com/v2-c150dfbe556f78f67b5abc945458278d_b.jpg" data-caption="" data-size="normal" data-rawwidth="2676" data-rawheight="1274" class="origin_image zh-lightbox-thumb" width="2676" data-original="https://pic2.zhimg.com/v2-c150dfbe556f78f67b5abc945458278d_r.jpg"/>

在namespace下的对象有(部分):

<img src="https://pic1.zhimg.com/v2-fcbe57f895ad2c7331f0efde0e96cff4_b.jpg" data-caption="" data-size="normal" data-rawwidth="2204" data-rawheight="2484" class="origin_image zh-lightbox-thumb" width="2204" data-original="https://pic1.zhimg.com/v2-fcbe57f895ad2c7331f0efde0e96cff4_r.jpg"/>

2.7 其他

K8S的对象实在太多了,2.1-2.6介绍的是在实际使用K8S部署服务最常见的。其他的还有Job、CronJob等等,在对K8S有了比较清楚的认知之后,再去学习更多的K8S对象,不是难事。


写在后面

本文是K8S系列文章第一篇,希望能够帮助对K8S不了解的新手快速了解K8S。如果文章中有纰漏,非常欢迎留言或者私信指出;有理解错误的地方,更是欢迎留言或者私信告知。

笔者一边写文章,一边查阅和整理K8S资料,过程中越发感觉K8S架构的完备、设计的精妙,是值得深入研究的,K8S大受欢迎是有道理的!再次感叹下。

K8S系列一:概念入门的更多相关文章

  1. K8s基本概念入门

    序言 没等到风来,绵绵小雨,所以写个随笔,聊聊k8s的基本概念. k8s是一个编排容器的工具,其实也是管理应用的全生命周期的一个工具,从创建应用,应用的部署,应用提供服务,扩容缩容应用,应用更新,都非 ...

  2. Docker & k8s 系列一:快速上手docker

    Docker & k8s 系列一:快速上手docker 本篇文章将会讲解:docker是什么?docker的安装,创建一个docker镜像,运行我们创建的docker镜像,发布自己的docke ...

  3. Go基础系列:channel入门

    Go channel系列: channel入门 为select设置超时时间 nil channel用法示例 双层channel用法示例 指定goroutine的执行顺序 channel基础 chann ...

  4. [转帖]新手必读,16个概念入门 Kubernetes

    新手必读,16个概念入门 Kubernetes https://www.kubernetes.org.cn/5906.html 2019-09-29 22:13 中文社区 分类:Kubernetes教 ...

  5. Docker & k8s 系列三:在k8s中部署单个服务实例

    本章将会讲解: pod的概念,以及如何向k8s中部署一个单体应用实例. 在上面的篇幅中,我们了解了docker,并制作.运行了docker镜像,然后将镜像发布至中央仓库了.然后又搭建了本机的k8s环境 ...

  6. SpringBoot系列之从入门到精通系列教程

    对应SpringBoot系列博客专栏,例子代码,本博客不定时更新 Spring框架:作为JavaEE框架领域的一款重要的开源框架,在企业应用开发中有着很重要的作用,同时Spring框架及其子框架很多, ...

  7. GraphQL 概念入门

    GraphQL 概念入门 Restful is Great! But GraphQL is Better. -- My Humble Opinion. GraphQL will do to REST ...

  8. 分布式学习系列【dubbo入门实践】

    分布式学习系列[dubbo入门实践] dubbo架构 组成部分:provider,consumer,registry,monitor: provider,consumer注册,订阅类似于消息队列的注册 ...

  9. 「译」JUnit 5 系列:基础入门

    原文地址:http://blog.codefx.org/libraries/junit-5-basics/ 原文日期:25, Feb, 2016 译文首发:Linesh 的博客:JUnit 5 系列: ...

  10. SpringBoot系列: RestTemplate 快速入门

    ====================================相关的文章====================================SpringBoot系列: 与Spring R ...

随机推荐

  1. .NET周刊【9月第4期 2023-09-24】

    国内文章 有趣的"可扩展近似计数"算法 https://zhuanlan.zhihu.com/p/656817283 在编程的世界里看见数学的身影,会让我充满好奇和兴奋.这不,在一 ...

  2. 【实操】Java+百度ocr,实现图片识别文字小工具

    前言 缘由 图片识别文字,咱用java也可以 通过java+百度ocr,实现一个截图或上传图片,图片识别文字的小工具.并通过exe4j工具将jar包封装成exe可执行桌面文件,方便使用及学习. Tip ...

  3. webwork学习

    学习了H5中的webworker 主机 > 程序 > 进程 > 线程 > 纤程 多进程(重) 多线程(轻) 开销 创建.销毁开销大 创建.销毁开销小 安全性 进程之间是隔离 线 ...

  4. matlab快速入门笔记

    命名规则: clc:清除命令行的所有命令 clear all:清除所有工作区的内容 注释:两个% + 空格 %% matlab的数据类型 1.数字 3 3 * 5 3 / 5 3 + 5 3 - 5 ...

  5. CF B. Gardener and the Array

    B. Gardener and the Array 思路:只要找到一个c他的每一位均在除了它的集合中出现过即可 这题T了2发,用来multiset,注意multiset大的时间复杂度是O(K + lo ...

  6. 面试题:MySQL事务的ACID如何实现?

    大家好,我是[码老思],事务是一个数据库绕不开的话题,今天和大家一起聊聊. 事务是什么? 事务(Transaction)是并发控制的基本单位.所谓的事务呢,它是一个操作序列,这些操作要么都执行,要么都 ...

  7. Nacos注册中心有几种调用方式?

    Spring Cloud Alibaba Nacos 作为近几年最热门的注册中心和配置中心,也被国内无数公司所使用,今天我们就来看下 Nacos 作为注册中心时,调用它的接口有几种方式? 1.什么是注 ...

  8. shopify本地开发 新的地方

    看了一些教程有些旧地方通不过,自己摸索下 1.创建app 点击Settings,再点击Apps and sales channels 点Allow custom app development 继续 ...

  9. 历时三年,写的一本数据结构与算法pdf,开源了!

    前言 大家好,我是bigsai,很早就在写博客,将文章整理成了一个pdf,并且开源到github上! 自己写东西断断续续也不少时间了,也写了不少东西(虽然是偏向小白),这个其实花费的时间还是比较多的, ...

  10. 字符串转换整数(atoi)(4.3leetcode每日打卡)

    一堆if不及python的一个正则表达式系列 请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止.接下来的转化规 ...