详解进程Fork
一. fork函数详解一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。
我们来看一个例子:
12345678910111213141516171819#include <unistd.h>#include <stdio.h>int main() { pid_t fpid; //fpid表示fork函数返回的值 int count = 0; fpid = fork(); if (fpid < 0) printf("error in fork!"); else if (fpid == 0) { printf("i am ...
深入理解Docker容器技术
本文参考转载至:《深入剖析Kubernetes - 张磊》
容器技术的核心功能,就是通过约束和修改进程的动态表现,从而为其创造出一个“边界”。对于 Docker 等大多数 Linux 容器来说,Cgroups 技术是用来制造约束的主要手段,而Namespace 技术则是用来修改进程视图的主要方法。你可能会觉得 Cgroups 和 Namespace 这两个概念很抽象,别担心,接下来我们一起动手实践一下,你就很容易理解这两项技术了。
一. Namespace假设你已经有了一个 Linux 操作系统上的 Docker 项目在运行,比如我的环境是 Ubuntu 16.04和 Docker CE 18.05。
接下来,让我们首先创建一个容器来试试。
12$ docker run -it busybox /bin/sh/ #
这个命令是 Docker 项目最重要的一个操作,即大名鼎鼎的 docker run。而 -it 参数告诉了 Docker 项目在启动容器后,需要给我们分配一个文本输入 / 输出环境,也就是 TTY,跟容器的标准输入相关联,这样我们就可以和这个 Docker ...
synchronized锁升级过程
JDK 1.6后锁的状态总共有四种,级别由低到高依次为:无锁、偏向锁、轻量级锁、重量级锁,这四种锁状态分别代表什么,为什么会有锁升级?
其实在 JDK 1.6之前,synchronized 还是一个重量级锁,底层使用操作系统的 Mutex Lock(互斥锁)实现,而操作系统实现线程之间的切换需要从用户态转换到核心态,这个成本非常高,状态之间的转换需要相对比较长的时间,这就是为什么重量级锁效率低的原因。
但是在JDK 1.6后,JVM为了提高锁的获取与释放效率对(synchronized )进行了优化,引入了 偏向锁 和 轻量级锁 ,从此以后锁的状态就有了四种(无锁、偏向锁、轻量级锁、重量级锁),并且四种状态会随着竞争的情况逐渐升级,而且是不可逆的过程,也就是说只能进行锁升级(从低级别到高级别),不能锁降级(高级别到低级别),这种设计目的是为了提高获得锁和释放锁的效率。
一. 对象的内存布局要弄清楚加锁过程到底发生了什么需要看一下对象创建之后再内存中的布局是个什么样的?
一个对象在new出来之后在内存中主要分为4个部分:
markword:默认存储对象的HashCode,分代年龄和锁标 ...
记一次线上内存泄露排查
一. 排查过程前不久测试环境一直无缘无故的挂掉,这可苦了我们一线开发人员,每次测试都得把挂掉服务全部起起来。面对几十个微服务模块,我想大家看到这样的场景内心也是一万个草泥马飞过….
硬着头皮把代码写完了,但是大规模的服务宕机显然不正常,看了一波还是热乎的日志,发现是服务器OOM了,顺道看了一下JVM配置,居然没有任何配置,看到这里嘴角丝丝上扬,觉得自己破案了。
随即给核心服务都加上了JVM参数:
1JAVA_OPTS: "-server -Xmx256m" #因为是测试环境对扩容抖动并不敏感,所以没有设置Xms,这样可以节省一点测试环境资源
改完配置,我觉的自己头不疼了,自己又行了。
第二天上班发现,测试环境还是挂了
带着满脸的问号,看了一波日志,结果还是OOM,但是挂的服务明显变少了。这一波我开始怀疑是不是测试环境应用内存给的确实太少了(线上是1GB),我把堆内存改成了512M:
1JAVA_OPTS: "-server -Xmx512m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/h ...
探寻Dubbo集群容错机制
一. timeout 与 retriesDubbo的服务可以通过timeout配置超时时间,防止远程调用失败,该属性的默认值为1000(ms),用户可以在多个地方配置服务的超时时间:
图中涉及的配置方式从上至下优先级越来越低,总体来说配置覆盖遵循以下规律:consumer配置优先于provider配置,细粒度配置优先于整体配置。
我们在消费者中sleep一段时间人为制造超时效果:
123456789101112131415161718@DubboService(timeout = 3000)@Slf4jpublic class UserServiceImpl implements IUserService{ @Override public UserDTO queryById(Integer userId) { if (userId == null) { throw new RuntimeException("参数不能为空"); } log.info(&q ...
使用OpenVPN搭建虚拟专用网
一. 初衷先说说自己搭建VPN的初衷,作为一个社畜在上海栖息之地是一间合租的卧室,房间虽小也抑制不住自己爱折腾的毛病,前不久自己在网上淘了一个M72主机,这个主机挺适合在家里当一个服务器,主要是因为它是I3处理功耗相对较低还是X86架构,相比用树莓派当服务器,不仅算力更强软件兼容性以及硬件可扩展性也更好。
因为日常开发学习过程中不免需要安装一些中间件应用,阿里云上可怜的2G内存显然是不允许我这样的操作(主要是财力不足)。没办法我只能将大部分应用部署在家庭内网服务器上。我给M72设置了一个固定的局域网IP,平常在家连接服务器会非常方便,但是一旦遇到外出的情况,家庭内网的服务器就完全访问不到了。
问题总归是要解决的,在Google上遨游了一番决定搭建一个内网穿透服务器,将家庭服务器的端口映射到公网服务器的某一个端口上。只要我访问公网服务器的这个端口,公网服务器就会把数据包转发到内网服务器上来。
网上的内网穿透方案非常多(frp,ngrok),最终选择了带WEB界面的 NPS,内网穿透的基本效果如下(至于内网穿透如何解决NAT网络模式下无法直接请求内网服务器的问题我们抽时间再谈):
配置 ...
一文让你弄懂Java SPI
SPI的英文全称为Service Provider Interface,字面意思为服务提供者接口,它是jdk提供给“服务提供厂商”或者“插件开发者”使用的接口。
在面向对象的设计中,模块之间我们一般会采取面向接口编程的方式,而在实际编程过程过程中,API的实现是封装在jar中,当我们想要换一种实现方法时,还要生成新的jar替换以前的实现类。而通过jdk的SPI机制就可以实现,首先不需要修改原来作为接口的jar的情况下,将原来实现的那个jar替换为另外一种实现的jar即可。
总结一下SPI的思想:在系统的各个模块中,往往有不同的实现方案,例如日志模块的方案、xml解析的方案等,为了在装载模块的时候不具体指明实现类,我们需要一种服务发现机制,java spi就提供这样一种机制。有点类似于IoC的思想,将服务装配的控制权移到程序之外,在模块化设计时尤其重要。
顺便提一下,Java SPI机制在很多大型中间件,例如Dubbo中均有采用,属于高级Java开发的进阶必备知识点,务必要求掌握。
一. SPI规范定义服务的通用接口,针对通用的服务接口,提供具体的实现类。
在jar包(服务提供者)的M ...
云原生时代,Java 的危与机(转)
本文转载至:云原生时代,Java的危与机-InfoQ
Java 诞生距今已有 25 年,但它仍然长期占据着“天下第一”编程语言的宝座。只是其统治地位并非坚不可摧,反倒可以说是危机四伏。云原生时代,Java 技术体系的许多前提假设都受到了挑战,目前已经有可预见的、足以威胁动摇其根基的潜在可能性正在酝酿。同时,像 Golang、Rust 这样的新生语言,以及 C、C++、C#、Python 等老对手也都对 Java 的市场份额虎视眈眈。面对危机,Java 正在尝试哪些变革?未来,Java 是会继续向前、再攀高峰,还是由盛转衰?
今天,25 岁的 Java 仍然是最具有统治力的编程语言,长期占据编程语言排行榜的首位,拥有一千二百万的庞大开发者群体,全世界有四百五十亿部物理设备使用着 Java 技术,同时,在云端数据中心的虚拟化环境里,还运行着超过两百五十亿个 Java 虚拟机的进程实例 (数据来自Oracle的WebCast)。
以上这些数据是 Java 过去 25 年巨大成就的功勋佐证,更是 Java 技术体系维持自己“天下第一”编程语言的坚实壁垒。Java 与其他语言竞争,底气从 ...
编辑距离(Levenshtein Distance)
一. 什么是Levenshtein DistanceLevenshtein Distance,一般称为编辑距离(Edit Distance,Levenshtein Distance只是编辑距离的其中一种)或者莱文斯坦距离,算法概念是俄罗斯科学家弗拉基米尔·莱文斯坦(Levenshtein · Vladimir I)在1965年提出。此算法的概念很简单:Levenshtein Distance指两个字串之间,由一个转换成另一个所需的最少编辑操作次数,允许的编辑操作包括:
将其中一个字符替换成另一个字符(Substitutions)。
插入一个字符(Insertions)。
删除一个字符(Deletions)。
二. 解题思路假如,我们定义个方法,入参为两个字符串,返回两个字符串的编辑距离:
1public static int editDistance(String a, String b);
假设我们有“kitte”、“Sitti”两个字符串,我们暂且将这两个字符串成为”A“和”B“,我们的编辑操作大致可分为三种类型:
选择一:将B字符串最后一个字符替换,使得两个字符串相等
...
网络广告代理商是如何通过 Cookie 收集用户信息的
不知道大家有没有这样的经历,我在某宝上搜索一个商品,然后再打开其它网站,它会非常“智能”的给我推荐同一商品。
这样的操作大多都是因为Cookie在搞鬼,在了解厂商这些骚操作前,我们先了解一下浏览器的同源策略。
一. 同源策略由于浏览器默认的同源策略只能获取到“自己”的Cookie。
所谓的同源策略就是指A网页设置的 Cookie,B网页不能打开,除非这两个网页”同源”。所谓”同源”指的是”三个相同”
协议相同
域名相同
端口相同
浏览器的同源策略会限制浏览器如下行为:
(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM 无法获得。
(3) AJAX 请求不能发送。
严格意义上的同源策略需要协议、域名、端口都保持一致,但是Cookie的同源策略只需要保证域名一致就行,默认情况下你访问https://zhidao.baidu.com产生的Cookie只有在访问zhidao.baidu.com这个三级域名(严格意义上.com .cn这种域名才属于一级域名)上才能使用,只是因为默认将Cookie的Domain设置为当前访问的域名。
但是 ...