2017-04-16 11:22:44    251    0    0

TCP连接的建立和终止

本文将阐述两个主机之间通过TCP协议通信的话需要哪些步骤,以及在建立连接的过程中经历哪些状态。并使用tcpdump工具帮助我们调试TCP应用,使我们掌握TCP如何建立和终止

TCP和UDP

首先的必须说一下TCP和UDP两种传输层协议;UDP是一种不可靠的传输协议,使用UDP协议时候,一个主机直接把一个数据报扔给另一个主机,而不考虑任何丢失的因数;所以UDP协议效率高不可靠。相反,TCP协议被定义为一种可靠传输协议,必须保证数据报一定要传输到对方(如果有意外,也会给出原因),要实现这种保证,就需要三次握手连接,传输数据确认,四次挥手告别,所以TCP协议是一种复杂,可靠的传输协议。

三次握手

当使用TCP协议传输数据时,为了保证数据的可靠传输,必须先建立连接,当建立一个TCP连接时,会发生以下情形
1. 客户端首先发送一个SYN分节,告诉服务器客户端将在连接中发送数据的初始序列号。
2. 服务器接收到客户端的SYN分节,必须发送一个确认(ACK),同时自己也得发送一个SYN分节,他告诉客户端服务器将在同一连接中发送数据的初始分节序列
3. 客户端收到服务器的SYN之后,发送一个ACK确认,三次握手完成

image

四次挥手

当两台主机使用TCP协议传输数据时,任何一方都不能擅自断开连接,否则后果很严重。比如数据接收方擅自断开连接之后,结果数据发送方还有数据需要发送,这样就会导致数据收发的不一致。所以,建立一个TCP协议需要三次握手,同样,断开一个TCP连接需要四次挥手
1. 某个应用进程首先调用close,则该端为主动关闭,该端的TCP发送一个FIN分节,表示数据发送完毕
2. 接收到这个FIN的对端称为被动关闭,这个传递过来的FIN由TCP确认,即发送一个ACK。它的接收也作为一个文件结束符传递给接收端应用进程。
3. 一段时间后,接收这个文件结束符的进程将调用close关闭它的套接字,这导致它的TCP也发送一个FIN
4.主动关闭的一段接收这个FIN并发送一个ACK确认

image

使用tcpdump调试

使用tcpdump命令可以查看指定网卡的数据分组交换情况,这里直接使用nginx实现的服务器,然后客户

2017-04-14 00:31:09    499    0    0

Socket网络编程入门

引子

从我们熟悉的web应用为例子,先不讨论socket,我们看一下如果两台机器之间要通讯,需要经过哪些步骤。我们看一下服务器回给我们一个简单的"Hi"时,需要经过哪些步骤。

image

服务端:

  1. 服务器的应用层会产生一个Hi字符串
  2. 数据封装后交给传输层
  3. 传输层封装后交给网络层
  4. 网络层数据封装后交给数据链路层
  5. 物理层接收后变成0和1字节流传输到Internet网络中

客户端:

  1. 客户端物理层接收来自服务端的0和1字节流
  2. 数据链路层接收物理层数据并解读数据报
  3. 网络层接收物理层数据并解读数据报
  4. 传输层解读网络层数据并解读数据报
  5. 应用层接收到Hi字符

现实中的网络数据传输远远比这复杂得多,数据必须经过5层协议栈。试想如果让一个开发者从0开始实现这样的一个数据传输,难度可想而知。但是目前从事网络开发的人千千万万,他们是怎么做到的呢,这一切都要归功于Unix操作系统和Socket。因为有了Socket,网络编程变得快速而且简单了很多。

什么是socket

Socket就是操作系统(Unix)为应用进程提供的一个方便操作网络数据收发的api接口,只要你读懂了这一套api接口,就可以把数据从一个主机传输到另一个主机,或者从其他主机接受数据,而不需要知道还有五层协议的复杂性。这就好比我们开发者读取文件的时候,file系列函数就可以轻松的帮我们获取文件的内容,我们不需要知道磁盘的磁头如何转动,如何实现定位读数据等。
下面是操作系统提供的Socket层的位置

image

这个图的上层是应用程序层,比如我们的nginx,apache系列的软件,下层是操作系统层,比如Unix。Socket层位于应用层和传输层之间,上层应用如果想实现网络编程,只需要调用操作系统提供的Socket层提供的api即可。操作系统通过Socket大大简化了网络编程的复杂性,使得从事网络编程的开发人员更加便捷。

Socket相关函数一览

既然知道了Socket是操作系统为我们提供的一层网络编程接口封装,那就可以看一下操作系统给我们留了哪些接口,我们能用这些接口干什么

函数名称 用途 说明
socket 创建套接字
2017-02-22 23:27:42    347    0    0

Hadoop+Hive环境搭建

JDK安装

由于国内城墙的原因,访问官网下载速度有点慢,这里csdn上下来资源。jdk安装包下载地址:

http://download.csdn.net/download/love254443233/9179483

下载下来上传到Linux服务器上,使用rz命令即可,如果没有这个命令,安装rz参照这篇文章

http://blog.csdn.net/kobejayandy/article/details/13291655

  1. 解压jdk-7u79-linux-x64.tar.gz
  1. [root@S140530 ~]# tar zxvf jdk-7u79-linux-x64.tar.gz
  1. 在/root/.bash_profile中添加如下配置
  1. export JAVA_HOME=/root/jdk1.7.0_79
  2. export PATH=$JAVA_HOME/bin:$PATH
  1. 使环境变量生效,执行以下命令
  1. [root@S140530 ~]# source ~/.bash_profile
  1. 安装验证,执行java命令
  1. [root@S140530 ~]# java -version
  2. java version "1.7.0_79"
  3. Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
  4. Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

Hadoop安装

下载解压

  1. 下载Hadoop2.7.1
  1. wget "http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.7.1/hadoop-2.7.1.tar.gz"
  1. 复制hadoop-2.7.1.tar.gz 到/usr/hadoop目录下
  1. [root@S140530 hadoop]# makedir /usr/hadoop
  2. [root@S140530 hadoop]# cp hadoop-2.7.1.tar.
2016-11-18 00:30:00    92    0    0

什么是索引

要理解MySQL中索引是如何工作的,最简单的办法就是看一本书的“索引”部分,就像给你一本新华字典,然后要你找出“爵”字,具体做法是根据拼音找出j开头的部分,然后再进一步定位到“爵”的页码,从而找出“爵”。MySQL索引的工作原理也一样。

B-Tree索引

当谈论索引的时候,如果没有特别申明,那多半是指B-Tree索引。B-Tree树意味着所有的值都是按顺序存储的,并且每一个叶子页到根的距离相同。在innoDB存储引擎中,抽象可以用以下图表示B-Tree树索引

B-Tree树能够加快访问数据的速度,因为存储引擎不再需要全表扫描获取需要的数据,取而代之的是从数据的根节点开始进行搜索。根节点的槽中存放了指向子节点的指针,存储引擎根据这些指针继续往下寻找,通过比较节点页的值和要查找的值就可以找到合适的指针进入下层节点,最终找到对应的值或者没找到结果。

MySQL中索引例子

假设有一张表的定义如下:

  1. create table people(
  2. last_name varchar(50) not null,
  3. first_name varchar(50) not null,
  4. dob date not null,
  5. gender enum('m', 'f') not null,
  6. key(last_name, first_name, dob)
  7. )

二级索引组织方式

则在B-Tree索引中,因为建立了一个last_name,first_name,dob的索引,注意key申明的索引为二级索引。数据的组织方式可以用以下图表示

特别注意的是,索引对多个值进行排序是按照create table定义语句中的定义索引的顺序来的,如果第一列一样,则排第二列,以此类推。按照这个数据组织方式,B-tree索引适合全键值键值范围键值前缀查找
以下查询都可以使用到索引
1. 查询一个姓名为Allen Cuba并且生日为1960-01-01的人
2. 查询所有姓Allen的人
3. 查询所有以A为开头自行姓名的人; last_name like ‘A%’
4. 查询姓Allen和Balnger之间的

2016-09-11 10:13:56    377    0    0

单块架构

在认识微服务之前,首先认识一下单块架构,很多互联网公司在创业初期都是采用单块架构,单块架构里将应用分成三层,表示层,逻辑层,访问层(数据)。然后部署在同一web容器上。
title
在单体架构里,以上能表示应用的所有代码,公司每个部门的人都在为这个代码仓库贡献代码,久而久之,代码变得非常庞大,笨重。每个部门的工作效率,交付能力变得越来越收到限制。主要表现为:

  1. 维护成本增加
  2. 交付周期长
  3. 新人培养周期长
  4. 技术选型受限制
  5. 扩展性差
  6. 构建全能团队难

为了改变这种现状,目前很多公司在尝试采用微服务去改造。但是,我们也可以得出,在创业初期其实是不适合做微服务的,因为创业初期需要以业务为主,本身业务不复杂的情况下很难拆分。但是,具备一定规模的公司微服务是相当有必要的。

什么是微服务

微服务目前为止很难有一个准确的定义,但是每个实践微服务的开发者目标是一致的。这里引用ThoughtWorks首席科学家——Martin fowler的一句话

微服务是一种架构模式,它倡导将单一应用程序划分成一组小的服务,服务之间相互协调,相互配合,为用户提供最终价值。每个服务运行在独立的进程中,服务与服务之间采用轻量级通信机制相互沟通(通常是基于HTTP的RESTful API)。每个服务都围绕着具体业务进行构建,并且能独立部署到生产环境,类生产环境等。每一个具体的服务而言,可以选择合适的语言和工具进行构建。

单一职责

如果你使用过Linux命令行,比如要找出当前目录下占用空间最多的5个资源

  1. du -s * | sort -nr | sed 5q

可以看到,这段命令行就是将几个常用的指令拼合起来完成任务。同样,在微服务架构中,也是这样的思路。对每个服务而言,我们希望它处理的业务能够单一,也就是说,微服务架构中的每个服务,都是具有业务逻辑的。不同的服务通过”管道”的方式灵活组合,从而构建出庞大的应用。

轻量级通讯

由于微服务化之后,每个微服务内部都可能采用不一样的语言,不一样的框架,所以微服务之间的通信尽量采用和语言无关,平台无关的方式。
title
对于轻量级通信格式而言,我们属性的XML或者JSON,他们的解析和使用基本与语言无关,平台无关。对于

2016-07-10 11:59:46    239    0    0

什么是SPL

SPL是Standard PHP Library(PHP标准库)的缩写。SPL包括以下内容
1. 数据结构
2. 迭代器
3. 基础接口
4. 异常
4. SPL函数
5. 文件处理

SPL数据结构

虽然我们可以使用传统的变量类型来描述数据结构,例如用数组来描述堆栈(Strack)– 然后使用对应的方式 pop 和 push(arraypop()、arraypush()),但你得时刻小心,·因为毕竟它们不是专门用于描述数据结构的 – 一次误操作就有可能破坏该堆栈。现在,有了SPL,就可以实现我们需要的数据结构

双向链表

双向链表的代码使用如下,更多详细信息可以参考:http://php.net/manual/zh/class.spldoublylinkedlist.php

  1. <?php
  2. /**
  3. * 双向链表
  4. */
  5. $obj = new SplDoublyLinkedList();
  6. $obj->push('yongxiong');//插入到顶部
  7. $obj->unshift('hahaha');//插入到底部
  8. $obj->rewind();//把指针指向底部
  9. echo $obj->current();//取出当前元素 hahaha
  10. $obj->next();//把指针指向下一个节点
  11. echo $obj->current();//yongxiong
  12. $obj->prev();//把指针指向上一个节点
  13. echo $obj->current();//hahahaha

注意,栈是双向链表的一个特例(继承双向链表),包括队列也是双向队列的一个特例。栈的代码操作实例,详细的SQL栈讲解:http://php.net/manual/zh/class.splstack.php

  1. <?php
  2. $obj = new SplStack();
  3. $obj->push(0);//进栈 等同于$obj[] = 0
  4. $obj->push(1);//进栈 等同于$obj[] = 1
  5. echo $obj->pop();//出栈 ,输出1

队列

队列也是继承双向链表,队列的代码实例,详细的队列的讲解:http://php.net/manual

2016-04-30 18:11:32    222    0    0

在PHP中应用回调例子

如果对js非常熟悉的话,一定对匿名函数,回调等概念不陌生

  1. $("#username").clcik(function(){
  2. //code
  3. $getJSON('/data.php', {name:name}, function(){
  4. //远程获取数据
  5. });
  6. });

相信写js的人对上面的代码一定不陌生,同样,PHP之道的发起人写的slim框架,也在大量使用类似的语法,比如下面一段slim的代码

  1. $app->get('/', function ($request, $response, $args) {
  2. return $response->write("Hello " . $args['name']);
  3. });

是不是写php跟写jQuery似的,非常有意思,Slim的作者是PHP和JavaScript程序员,同时也是《PHP The Right Way》的作者,相信js工程师也一定非常喜欢这样的语法。

PHP创建闭包

注意,在PHP中,匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然,也有其它应用的情况。比如官网一个闭包函数的例子

  1. <?php
  2. echo preg_replace_callback('~-([a-z])~', function ($match) {
  3. return strtoupper($match[1]);
  4. }, 'hello-world');
  5. // 输出 helloWorld

闭包函数也可以作为变量的值来使用。PHP 会自动把此种表达式转换成内置类 Closure 的对象实例。把一个 closure 对象赋值给一个变量的方式与普通变量赋值的语法是一样的,最后也要加上分号:

  1. <?php
  2. $add = function($a, $b){
  3. return $a + $b;
  4. };
  5. echo $add(3,4);//输出7

注意,闭包函数构建了自己个一个作用域,如果需要使用父级作用域中的变量,必须使用use关键字

2016-03-20 23:48:41    188    1    0

memcached介绍

memcache是danga.com的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。它可以应对任意多个连接,使用非阻塞的网络IO。由于它的工作机制是在内存中开辟一块空间,然后建立一个HashTable,memcached自管理这些HashTable。为什么会有Memcache和memcached两种名称?
其实memcache是这个项目的名称,而memcached是它服务器端的主程序文件名。Memcache在高并发的情况下通过将热数据缓存到内存中来降低数据库的压力,这是目前很多网站使用Memcache的原因。

memcached的安装

memcached的安装非常简单,去官方网站下载http://memcached.org/downloads最新的memcached资源,安装方式很简单,官方例子。唯一比较不能接受的一点是,城外的网都比较慢

wget http://memcached.org/latest
tar -zxvf memcached-1.x.x.tar.gz
cd memcached-1.x.x
./configure && make && make test && sudo make install

启动memcached服务

进入到memcached的安装目录,然后通过daemon的方式启动起来。

localhost:Downloads MLS$ cd memcached-1.4.23
localhost:memcached-1.4.23 MLS$ ./memcached -d

检查memcached进程是否已经启动起来:

localhost:memcached-1.4.23 MLS$ ps -ef | grep memcached | grep -v grep
501  6978     1   0  9:37下午 ??         0:00.01 ./memcached -d

可以看到memcached服务以daemon的形式在后台运行,我们并没有制定端口和IP。memcach

2016-03-20 23:42:20    141    0    0

为什么要使用PHP自动加载

php自动装载就是根据需要自动加载php类,而不需要显示的include文件。在一个项目中,如果一个文件有过多的include依赖,那自动加载将会使这种情况变得好转。

  1. <?php
  2. include "/libs/Token.class.php";
  3. include "/libs/Auth.class.php";
  4. include "/libs/Db.class.php";
  5. include "/libs/Image.class.php";
  6. ...//更多加载
  7. class UserRegister {
  8. //code
  9. }
  10. ?>

写一堆include是不是很费劲?有的人可能会说还好,但是再看一个例子

  1. <?php
  2. require "libs/Memcache.class.php";
  3. require "libs/Redis.class.php";
  4. if(Config::getCacheMode() == "memcache"){
  5. $info = Memcache::get(1);
  6. }else{
  7. $info = Redis::get(1);
  8. }
  9. echo $info;

这个例子其实就是资源浪费了,因为无论如何,if-else只有一个分支回进去,当使用Memcache模式时,Redis引入进来是没有必要的;同样,当使用Redis模式时候,没有必要引入Memcache;
这时候,可以通过PHP的__autoload方法提供一种lazyload的机制,当第一次需要使用相关类时调用,这样就不会加载不必要的类。

实现自动加载的方式

__autoload方式

php应用中,当我们实例化类的时候,如果在当前文件中找不到这个类,php会自动执行一个函数__autoload;看下面的例子:

  1. <?php
  2. function __autoload($class){
  3. echo "自动执行我";
  4. }
  5. new Memcahce();
  6. ?>

运行php文件可以看到,__autoload函数被自动执行了,然后提示没有找这个类

  1. localhost:autoload MLS$ php index.php
  2. 自动执行我PHP Fatal erro
MySQL    2016-03-02 22:30:27    173    0    0

数据库设计范式介绍

关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴德斯科范式(BCNF)、第四范式(4NF)和第五范式(5NF)

  • 第一范式(确保每列保持原子性)
    第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式

  • 第二范式(确保表中的每列都和主键完全依赖)
    需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中

  • 第三范式(在第二范式的基础上,消除传递依赖)
    需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关

当然还有更高的范式,单是它们的关系总是先满足1NF,然后在1NF上改进成2NF,以此类推,所以范式之间的关系可以用以下图表示:

第一范式

1NF是数据库设计的最基本范式,在关系型数据库中,如果一个域是原子的,并且该域的元素被认为是不可分的单元,我们就称符合这种设计的表满足1NF,比如下面一张商品表:
商品信息表

商品ID 商品名称 颜色 价格 商家名字 商家联系方式
1 韩版休闲裤 50.0 张三 13634589384
1 韩版休闲裤 60.0 张三 13634589384
2 欧式西装 140.0 李四 13234534543

这张表就符合1NF,每一列都不可再分。
1NF的缺点有以下
1. 数据冗余太大,商家名字和商家联系方式大量冗余
2. 更新异常,需要更改商家联系方式的时候,需要修改大量的信息
3. 插入异常,如果一个商家刚成立,没有发布商品,插入会导致异常
4. 删除异常,如果一个商家的商品全部删除,商家随着被删除
思考?
下面这收件地址张表符合1NF吗?

收件人 街道 详细地址
张三 江西省 赣州市 章贡区 钟楼大街 幸福小区503号楼22#

还有很

2/3