分类目录: 软件技术

DNS原理、架构和配置详解

题目起得有点大,其实都是一些基础知识。工作、生活中经常被问到DNS的工作原理,这里把相关的知识点总结一下。DNS作为域名解析的规范,本身是相当简单的,但是因为我们日常工作中很难接触到,因此对其工作原理、架构和配置等就显得非常陌生。在分布式系统中,DNS更是扮演着重要的角色。名字空间和网域的划分都要依赖他。

一、我们日常网络活动能感受的域名解析服务

首先从我们日常生活中能看到的DNS模型说起,一般而言我们都知道DNS是做什么的:将容易记住的网址转换成网站的IP地址(网站,确切的说是提供web服务的主机的IP地址)。那么这一过程是如何发生的呢?下面的流程图给出了这一过程。偷点懒,图片没有自己画,都是在网络上面找来的(Google图片搜索-DNS查询)。

DNS查询示意图

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 10票) Loading ... Loading ... | 同时归档在:移动互联 | 标签: , , , , , , |

精选实用正则表达式

匹配中文字符的正则表达式: [\u4e00-\u9fa5]
评注:匹配中文还真是个头疼的事,有了这个表达式就好办了

匹配双字节字符(包括汉字在内):[^\x00-\xff]
评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)

匹配空白行的正则表达式:\n\s*\r
评注:可以用来删除空白行

匹配HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? />
评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力

匹配首尾空白字符的正则表达式:^\s*|\s*$
评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式

匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
评注:表单验证时很实用

匹配网址URL的正则表达式:[a-zA-z]+://[^\s]*
评注:网上流传的版本功能很有限,上面这个基本可以满足需求

匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
评注:表单验证时很实用

匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
评注:匹配形式如 0511-4405222 或 021-87888822

匹配腾讯QQ号:[1-9][0-9]{4,}
评注:腾讯QQ号从10000开始

匹配中国邮政编码:[1-9]\d{5}(?!\d)
评注:中国邮政编码为6位数字

匹配身份证:\d{15}|\d{18}
评注:中国的身份证为15位或18位

匹配ip地址:\d+\.\d+\.\d+\.\d+

评注:提取ip地址时有用

匹配特定数字:
^[1-9]\d*$    //匹配正整数
^-[1-9]\d*$   //匹配负整数
^-?[1-9]\d*$   //匹配整数
^[1-9]\d*|0$  //匹配非负整数(正整数 + 0)
^-[1-9]\d*|0$   //匹配非正整数(负整数 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$   //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$  //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$  //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$   //匹配非负浮点数(正浮点数 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$  //匹配非正浮点数(负浮点数 + 0)
评注:处理大量数据时有用,具体应用时注意修正

匹配特定字符串:
^[A-Za-z]+$  //匹配由26个英文字母组成的字符串
^[A-Z]+$  //匹配由26个英文字母的大写组成的字符串
^[a-z]+$  //匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$  //匹配由数字和26个英文字母组成的字符串
^\w+$  //匹配由数字、26个英文字母或者下划线组成的字符串
评注:最基本也是最常用的一些表达式

| 1 分2 分3 分4 分5 分 (5.00- 1票) Loading ... Loading ... | 同时归档在:实用脚本 | 标签: , |

精选37条强大的常用linux shell命令组合

| 1 分2 分3 分4 分5 分 (5.00- 6票) Loading ... Loading ... | 同时归档在:实用脚本 | 标签: , , |

二阶段提交及相关学习笔记

在分布式数据库中,处理分布式事务是比较重要的技术。分布式事务的处理保证了数据的一致性。二阶段提交在可用性和一致性性上面做到了最好的折中。是一种基本的事务处理机制或者协议。

对于二阶段提交的准确解释可以参考维基百科词条:http://zh.wikipedia.org/wiki/%E4%BA%8C%E9%98%B6%E6%AE%B5%E6%8F%90%E4%BA%A4

二阶段提交(Two-phase Commit)

理解二阶段提交关键是要结合redo、undo日志,日志可以固化到DB中,也可以回滚即丢弃,基于此,才能做到预提交与实际提交的分离。

在分布式系统中,一般来说不止是1个协调者与2~3个参与者之间交互,当考虑容错性时,通常会考虑如下场景:

协调者在完成了一阶段的预提交过程后,得出了本事务的执行结论,在本地日志中记录了结论,正待向参与者发出结论时,宕机,这样除了协调者本身之外,就没有人知道该事务的结论。因此必须等待协调者恢复之后才能继续该事务,在此之前所有参与者都将阻塞。各个阶段所获取的资源一直不释放,可能导致整个集群业务受阻。

解决该问题的办法是将第二阶段(正式提交阶段)再变为两个阶段,先让集群中若干个参与者知道自己将要提交结论,而不是记录本地日志,这样该协调者无论在哪个阶段宕机,都可以由新选出的协调者通过查询各个参与节点的状态来判断当前处于哪个阶段,从而继续后面的各个阶段的操作。也就是三阶段提交了,这样参与者与协调者的交互步骤增加,实际操作起来也变得复杂很多,因此实用性不强。

| 1 分2 分3 分4 分5 分 (5.00- 1票) Loading ... Loading ... | 归档目录:软件技术 | 标签: , , |

[转] 几大分布式文件系统全方位比较

转载信息:

作者:朱荣泽
原文地址:http://blog.csdn.net/metaxen/article/details/7108958

阅读链接:

分布式文件系统MFS、Ceph、GlusterFS、Lustre的比较

| 1 分2 分3 分4 分5 分 (5.00- 4票) Loading ... Loading ... | 归档目录:软件技术 | 标签: , , , , |

[转] 深入多线程编程

线程库
多线程编程定式
无锁编程(Lock Free)
阻塞型同步(Blocking Synchronization)
非阻塞型同步(Non-blocking Synchronization)
优先级反转(Priority Inversion)
优先级继承(Priority Inheritance)
优先级顶置(Priority Overhead)
内存屏障

转载自:http://blog.chinaunix.net/uid-20682147-id-3160080.html

PDF文档查阅链接:

深入多线程编程

| 1 分2 分3 分4 分5 分 (5.00- 1票) Loading ... Loading ... | 同时归档在:多线程编程 | 标签: , , |

一道基础的词法解析题

原日志信息
标题:《计算单词数目的小程序-2009-05-24考试》
发布时间:5/24/2009
作者:童燕群

2009年,公司开始推行技能鉴定考试,这是我第一次参加的技能鉴定考试,那次考试最终以成绩不作为技术等级评定的依据收场。据说有的部门直接以金钱来奖励考分高者,在天涯论坛上面闹得沸沸扬扬。当年做这道题目时用完了所有考试时间,但是仍然没有调通,晚上回家后又接着奋战几个小时,重新写了这份代码。在现在看来,当时那个迫切想写代码的心情真的是难以理解。软件维护工作做多了,好像是会有这样的感觉。

直接贴代码,题目在代码头部的注释中。

阅读全文 »

| 1 分2 分3 分4 分5 分 (4.86- 7票) Loading ... Loading ... | 同时归档在:C/C++, 算法数据结构, 职业发展 | 标签: , |

[分享]百度分布式数据库

很老的视频了,感觉讲得不错,百度09年都已经SSD了,我们却还在挣扎着怎样精简流程来节省元数据的访问。右边是视频中用于讲解的PPT。

  

| 1 分2 分3 分4 分5 分 (5.00- 1票) Loading ... Loading ... | 同时归档在:移动互联 | 标签: , |

一个明显的jetty-8大文件传输性能大幅降低问题分析

这个问题很早就分析、修改和验证过了,一直没有来得及总结整理。今天突然想起来了,首先用我那蹩脚的英语给jetty的维护团队提了一个问题单,在等待他们回复的同时,我也把我发现问题的过程分享一下。

问题单链接:https://bugs.eclipse.org/bugs/show_bug.cgi?id=415282

经过打断点和调试,发现如下调用占用了性能下降(相对于jetty7版本)的绝大多数处理耗时:

public class HttpOutput extends ServletOutputStream 
{
/* ------------------------------------------------------------ */
private void write(Buffer buffer) throws IOException
{
if (_closed)
throw new IOException("Closed");
if (!_generator.isOpen())
throw new EofException();

// Block until we can add _content.
while (_generator.isBufferFull())
{
_generator.blockForOutput(getMaxIdleTime());
if (_closed)
throw new IOException("Closed");
if (!_generator.isOpen())
throw new EofException();
}

// Add the _content
_generator.addContent(buffer, Generator.MORE);

// Have to flush and complete headers?

if (_generator.isAllContentWritten())
{
flush();
close();
}
else if (_generator.isBufferFull())
_connection.commitResponse(Generator.MORE);

// Block until our buffer is free
while (buffer.length() > 0 && _generator.isOpen())
{
_generator.blockForOutput(getMaxIdleTime());
}
}
}
具体的耗时消耗在:_generator.blockForOutput(getMaxIdleTime());
从函数名字都可以看出来,当网络繁忙时,会走到这个流程,在blockForOutPut中,首先会注册一个socket可写的事件,当该socket上面可以写数据时,通知当前业务线程,随后业务线程投入休眠。等待事件分发线程检查可读事件,并唤醒自己。这样在这个交互中不可避免的会损失部分数据传输性能,每一包数据虽然只会损失一点点性能,但是传输一个很大的文件时,就会发现这个损失的巨大,在10GE的网卡上面,数据传输的性能降低到了原来的1/10,这个影响太明显了。
 
那么问题到底出在哪里呢?
看下面的代码:
public class HttpGenerator extends AbstractGenerator
{
public void addContent(Buffer content, boolean last) throws IOException
{
if (_noContent)
throw new IllegalStateException("NO CONTENT");

if (_last || _state==STATE_END)
{
LOG.warn("Ignoring extra content {}",content);
content.clear();
return;
}
_last = last;

// Handle any unfinished business?
if (_content!=null && _content.length()>0 || _bufferChunked)
{
if (_endp.isOutputShutdown())
throw new EofException();
flushBuffer();
if (_content != null && _content.length()>0)
{
if (_bufferChunked)
{
Buffer nc=_buffers.getBuffer(_content.length()+CHUNK_SPACE+content.length());
nc.put(_content);
nc.put(HttpTokens.CRLF);
BufferUtil.putHexInt(nc, content.length());
nc.put(HttpTokens.CRLF);
nc.put(content);
content=nc;
}
else
{
Buffer nc=_buffers.getBuffer(_content.length()+content.length());
nc.put(_content);
nc.put(content);
content=nc;
}
}
}

_content = content;
_contentWritten += content.length();

// Handle the _content
if (_head)
{
content.clear();
_content=null;
}
else if (_endp != null && (_buffer==null || _buffer.length()==0) && _content.length() > 0 && (_last || isCommitted() && _content.length()>1024))
{
_bypass = true;
}
else if (!_bufferChunked)
{
// Yes - so we better check we have a buffer
if (_buffer == null)
_buffer = _buffers.getBuffer();

// Copy _content to buffer;
int len=_buffer.put(_content);
_content.skip(len);
if (_content.length() == 0)
_content = null;
}
}
}
 
问题出在下面这段代码上面:
// Handle the _content
if (_head)
{
content.clear();
_content=null;
}
else if (_endp != null && (_buffer==null || _buffer.length()==0) && _content.length() > 0 && (_last || isCommitted() && _content.length()>1024))
{
_bypass = true;
}
else if (!_bufferChunked)
{
// Yes - so we better check we have a buffer
if (_buffer == null)
_buffer = _buffers.getBuffer();

// Copy _content to buffer;
int len=_buffer.put(_content);
_content.skip(len);
if (_content.length() == 0)
_content = null;
}
我的理解,_bypass变量标志不使用缓存,直接将数据刷到客户端,如果这是jetty8的新增特性,那么也不应该是到外层再调用blockforoutput方法,而是直接flushbuffer即可。很明显这是一个bug,bypass的判断条件有误,_buffer为空,这是不使用缓存的条件,但是_buffer.length() == 0并不是该特性的条件,每一次初始化的时候都会默认操作_buffer使得_buffer.length() == 0。这样就导致了每一包数据都走进了blockforoutput流程。应该是一个明显的笔误,问题的修改方法即是去掉该不当的判断条件,只保留_buffer==null的判断。
 
同前面的jetty若干性能问题的分析一样,这个问题的分析也耗费了大量的时间和精力,最终是借助于比对jetty7和jetty8的代码和不停的加日志打点调试得出的。每一个问题的解决都是一段辛酸的故事。
| 1 分2 分3 分4 分5 分 (5.00- 18票) Loading ... Loading ... | 同时归档在:Jetty | 标签: , |

Java网络应用程序(Geronimo、Jetty)调试及问题定位方法简介

Java网络应用程序调试及问题定位方法简介

| 1 分2 分3 分4 分5 分 (5.00- 3票) Loading ... Loading ... | 同时归档在:Geronimo, Java, Jetty, 实用脚本 | 标签: , , |
返回顶部