DooD:Docker+Jenkins

DooD:Docker+Jenkins

1. 基础环境 本文基于64位的CentOS 7.2系统,内核版本如下: 图1 宿主机的操作系统内核版本 Docker版本如下: 图2 Docker版本 如需安装Docker,请点击:安装Docker 如需安装Docker加速器,请点击:配置Docker加速器 2.在容器中调用docker命令有以下几种方式 2.1 DooD(Docker-outside-of-Docker) 其实就是运行一个Jenkins镜像的docker容器,这种方式使用socket套接字(一般默认是/var/run/docker.sock文件)和宿主机进行交互,只限于本地通信。不会去监听任何端口。在创建Jenkins镜像时,可以给jenkins用户赋予sudo权限来调用docker命令;或者将jenkins用户加入到docker组,就可以直接在容器中调用docker命令,下文会分别讲到两种情况的Dockerfile的写法。不过相比较于不同的宿主机docker组的不同,使用sudo更具有普适性和可移植性。 2.2 DinD(Docker in Docker) 顾名思义,就是在Docker容器中重新安装一个Docker应用。容器中安装Docker和宿主机安装的Docker是完全没有关联的两个程序。一般情况下,我们想要的只是一个运行于docker的CI/CD环境,我们需要容器内外只有一个docker engine。 DinD显然比我们想要的要复杂的多,而且可能还有一些意想不到的问题会出现。 更详细的了解,请参考下面两篇文章: https://zhuanlan.zhihu.com/p/27208085 https://github.com/jpetazzo/dind 2.3 使用HTTP/HTTPS与Docker Engine通讯 Docker还可以对外暴露Remote API,通过http/https就可以与docker engine进行通信,因为打开Remote API相应的要对外暴露端口,所以相对来说是不安全的。 在Jenkins容器中可以通过配置相应的Docker plugin,并在“系统管理”——>“系统设置”——>“云”中增添响应的Remote API信息。 详细信息请参考: https://docs.docker.com/engine/security/https/ 进过对比,我使用的是第一种方式:DooD。 注意点:请确保宿主机的doeker server已经开启本地套接字访问和远程通信 3.在宿主机上开启本地套接字访问和远程通信 默认情况下,Docker守护进程会生成一个socket(/var/run/docker.sock)文件来进行本地进程通信,而不会监听任何端口,因此只能在本地使用docker客户端或者使用Docker API进行操作。 如果想在其他主机上操作Docker主机,就需要让Docker守护进程监听一个端口,这样才能实现远程通信。 目前开启本地套接字访问和远程通信有以下两种方式: 3.1 修改/etc/docker/daemon.json 把以下内容添加进json文件中,注意添加前请确认23

聊聊TCP连接耗时的那些事儿

聊聊TCP连接耗时的那些事儿

在互联网后端日常开发接口的时候中,不管你使用的是C、Java、PHP还是Golang,都避免不了需要调用mysql、redis等组件来获取数据,可能还需要执行一些rpc远程调用,或者再调用一些其它restful api。 在这些调用的底层,基本都是在使用TCP协议进行传输。这是因为在传输层协议中,TCP协议具备可靠的连接,错误重传,拥塞控制等优点,所以目前应用比UDP更广泛一些。 相信你也一定听闻过TCP也存在一些缺点,那就是老生常谈的开销要略大。但是各路技术博客里都在单单说开销大、或者开销小,而少见不给出具体的量化分析。不客气一点,这都是营养不大的废话。经过日常工作的思考之后,我更想弄明白的是,开销到底多大。一条TCP连接的建立需要耗时延迟多少,是多少毫秒,还是多少微秒?能不能有一个哪怕是粗略的量化估计?当然影响TCP耗时的因素有很多,比如网络丢包等等。我今天只分享我在工作实践中遇到的比较高发的各种情况。 正常TCP连接建立过程 要想搞清楚TCP连接的建立耗时,我们需要详细了解连接的建立过程。在前文《图解Linux网络包接收过程》中我们介绍了数据包在接收端是怎么被接收的。数据包从发送方出来,经过网络到达接收方的网卡。在接收方网卡将数据包DMA到RingBuffer后,内核经过硬中断、软中断等机制来处理(如果发送的是用户数据的话,最后会发送到socket的接收队列中,并唤醒用户进程)。 在软中断中,当一个包被内核从RingBuffer中摘下来的时候,在内核中是用struct sk_buff结构体来表示的(参见内核代码include/linux/skbuff.h)。其中的data成员是接收到的数据,在协议栈逐层被处理的时候,通过修改指针指向data的不同位置,来找到每一层协议关心的数据。 对于TCP协议包来说,它的Header中有一个重要的字段-flags。如下图: 通过设置不同的标记为,将TCP包分成SYNC、FIN、ACK、RST等类型。客户端通过connect系统调用命令内核发出SYNC、ACK等包来实现和服务器TCP连接的建立。在服务器端,可能会接收许许多多的连接请求,内核还需要借助一些辅助数据结构-半连接队列和全连接队列。我们来看一下整个连接过程: 在这个连接过程中,我们来简单分析一下每一步的耗时 客户端发出SYNC包:客户端一般是通过connect系统调用来发出SYN的,这里牵涉到本机的系统调用和软中断的CPU耗时开销 SYN传到服务器:SYN从客户端网卡被发出,开始“跨过山和大海,也穿过人山人海......”,这是一次长途远距离的网络传输 服务器处理SYN包:内核通过软中断来收包,

java内存查看与分析

java内存查看与分析

业界有很多强大的java profile的工具,比如Jporfiler,yourkit,这些收费的东西我就不想说了,想说的是,其实java自己就提供了很多内存监控的小工具,下面列举的工具只是一小部分,仔细研究下jdk的工具,还是蛮有意思的呢:) 1:gc日志输出 在jvm启动参数中加入 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimestamps -XX:+PrintGCApplicationStopedTime,jvm将会按照这些参数顺序输出gc概要信息,详细信息,gc时间信息,gc造成的应用暂停时间。如果在刚才的参数后面加入参数 -Xloggc:文件路径,gc信息将会输出到指定的文件中。其他参数还有 -verbose:gc和-XX:+PrintTenuringDistribution等。 2:jconsole jconsole是jdk自带的一个内存分析工具,它提供了图形界面。可以查看到被监控的jvm的内存信息,线程信息,类加载信息,MBean信息。 jconsole位于jdk目录下的bin目录,在windows下是jconsole.exe,在unix和linux下是jconsole.sh,jconsole可以监控本地应用,也可以监控远程应用。 要监控本地应用,执行jconsole pid,pid就是运行的java进程id,如果不带上pid参数,则执行jconsole命令后,会看到一个对话框弹出,上面列出了本地的java进程,可以选择一个进行监控。如果要远程监控,则要在远程服务器的jvm参数里加入一些东西,因为jconsole的远程监控基于jmx的,关于jconsole详细用法,请见专门介绍jconsle的文章,我也会在博客里专门详细介绍jconsole。 3:jviusalvm 在JDK6 update 7之后,jdk推出了另外一个工具:jvisualvm,java可视化虚拟机,它不但提供了jconsole类似的功能,还提供了jvm内存和cpu实时诊断,还有手动dump出jvm内存情况,手动执行gc。 和jconsole一样,运行jviusalvm,在jdk的bin目录下执行jviusalvm,windows下是jviusalvm.exe,linux和unix下是jviusalvm.sh。 4:jmap jmap是jdk自带的jvm内存分析的工具,位于jdk的bin目录。jdk1.6中jmap命令用法: Html代码 Usage: jmap -histo <pid> (to connect to running process and print histogram of java object heap jmap -dump:<dump-options> <pid> (to connect to running process and dump java heap) dump-options: format=b binary default file=<file> dump heap to <file> Example: jmap -dump:format=b,file=heap.bin <pid> jmap -histo <pid>在屏幕上显示出指定pid的jvm内存状况。以我本机为例,执行该命令,屏幕显示: Html代码 1: 24206 2791864 < constMethodKlass >

java内存分析工具 jmap,jhat及dump分析

java内存分析工具 jmap,jhat及dump分析

jmap -heap 1234 查看进程号为1234的Java程序的整个jvm内存状态 jmap -histo 1234 查找进程号为1234的java程序的jvm堆中对象详细占用情况 jmap -dump:format=b,file=/my.dump 1234 导出1234进程的java程序的整个JVM信息 jhat -J-Xmx1024M /my.dump, 启动web服务查看jmap导出的java程序的jvm信息。 jstack 1234 查看1234进程的所有堆栈信息。 以上命令的功能都可以从jVisualVM程序获取,双击运行即可。 jmap是java自带的工具 查看整个JVM内存状态 jmap -heap [pid] 要注意的是在使用CMS GC 情况下,jmap -heap的执行有可能会导致JAVA 进程挂起 查看JVM堆中对象详细占用情况 jmap -histo [pid] 导出整个JVM 中内存信息 jmap -dump:format=b,file=文件名 [pid] jhat是sun 1.6及以上版本中自带的一个用于分析JVM 堆DUMP 文件的工具,基于此工具可分析JVM HEAP 中对象的内存占用情况 jhat -J-Xmx1024M [file] (此处的file指的是jmap -dump导出的内存数据文件) 执行后等待console 中输入start HTTP server on port 7000 即可使用浏览器访问 IP:7000 eclipse Memory Analyzer Eclipse 提供的一个用于分析JVM 堆Dump文件的插件。借助这个插件可查看对象的内存占用状况,引用关系,分析内存泄露等。 http://www.eclipse.org/mat/ kill -3 [pid] 在Linux 上找到Java所在的进程号,然后执行以上命令,线程的相关信息就输出到console jstack jstack 是sun JDK 自带的工具,通过该工具可以看到JVM 中线程的运行状况,包括锁等待,线程是否在运行 执行 jstack [pid] ,线程的所有堆栈信息 "http-8080-10" daemon prio=10 tid=x0a949bb60 nid=0x884 waiting for monitor entry [...] "http-8080-10" 这个线程处于等待状态。 waiting for monitor entry 如果在连续几次输出线程堆栈信息都存在于同一个或多个线程上时,则说明系统中有锁竞争激烈,死锁,或锁饿死的想象。 “http-8080-11” daemon prio=10 tix=xxx nid=xxx in object.wait() [...] java.lang.Thread.State:waiting (on object monitor) 该表示http-8080-11的线程处于对象的Wait 上,等待其他线程的唤醒,这也是线程池的常见用法。 “Low Memory Detector”daemon prio=10 tix=xx nid=xxx runnable [...] java.lang.Thread.State:runnable 表示“Low Memory Detector” 的线程处于Runable状态,等待获取CPU的使用权. 参考:http://zhumeng8337797.blog.163.com/blog/static/10076891420124241058318

一口气说出9种分布式ID生成方式,面试官有点懵了

一口气说出9种分布式ID生成方式,面试官有点懵了

一、为什么要用分布式ID? 在说分布式ID的具体实现之前,我们来简单分析一下为什么用分布式ID?分布式ID应该满足哪些特征? 1、什么是分布式ID? 拿MySQL数据库举个栗子: 在我们业务数据量不大的时候,单库单表完全可以支撑现有业务,数据再大一点搞个MySQL主从同步读写分离也能对付。 但随着数据日渐增长,主从同步也扛不住了,就需要对数据库进行分库分表,但分库分表后需要有一个唯一ID来标识一条数据,数据库的自增ID显然不能满足需求;特别一点的如订单、优惠券也都需要有唯一ID做标识。此时一个能够生成全局唯一ID的系统是非常必要的。那么这个全局唯一ID就叫分布式ID。 2、那么分布式ID需要满足那些条件? 全局唯一:必须保证ID是全局性唯一的,基本要求 高性能:高可用低延时,ID生成响应要块,否则反倒会成为业务瓶颈 高可用:100%的可用性是骗人的,但是也要无限接近于100%的可用性 好接入:要秉着拿来即用的设计原则,在系统设计和实现上要尽可能的简单 趋势递增:最好趋势递增,这个要求就得看具体业务场景了,一般不严格要求 二、 分布式ID都有哪些生成方式? 今天主要分析一下以下9种,分布式ID生成器方式以及优缺点: UUID 数据库自增ID 数据库多主模式 号段模式 Redis 雪花算法(SnowFlake) 滴滴出品(TinyID) 百度 (Uidgenerator) 美团(Leaf) 那么它们都是如何实现?以及各自有什么优缺点?我们往下看 图片源自网络,如有侵权联系删除 1、基于UUID 在Java的世界里,想要得到一个具有唯一性的ID,首先被想到可能就是UUID,毕竟它有着全球唯一的特性。那么UUID可以做分布式ID吗?答案是可以的,但是并不推荐! public static void main(String[] args) { String uuid = UUID.randomUUID().toString().replaceAll("-",""); System.out.println(uuid); } UUID的生成简单到只有一行代码,输出结果 c2b8c2b9e46c47e3b30dca3b0d447718,但UUID却并不适用于实际的业务需求。像用作订单号UUID这样的字符串没有丝毫的意义,看不出和订单相关的有用信息;而对于数据库来说用作业务主键ID,它不仅是太长还是字符串,存储性能差查询也很耗时,所以不推荐用作分布式ID。 优点: 生成足够简单,本地生成无网络消耗,具有唯一性 缺点: 无序的字符串,不具备趋势自增特性 没有具体的业务含义 长度过长16 字节128位,36位长度的字符串,存储以及查询对MySQL的性能消耗较大,MySQL官方明确建议主键要尽量越短越好,作为数据库

联系我们

联系电话

4000-640-466

联系邮箱

service@f-li.cn

办公地址

上海黄浦区外滩源1号

谢谢,您的信息已成功发送。
请填写信息。