2016-09-11 10:13:56    593    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    500    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    618    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    372    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    303    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    337    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#

还有很

2016-02-23 11:34:31    5328    0    1

前言

本文目的旨在对http状态码含义做一个基本解释,不会太深入讨论每个状态码,由于每个http状态码的出现可能对应多种情况,本文可能也考虑不周全。总之,看完本文,能够对http状态码有一个更加直观的认知。本文的思路是一个状态码加一个重现例子的方式呈现。

坏境搭建

本文的测试需要的linux+nginx+PHP环境,可以不需要MySQL。搭建环境的资料如下:
lnmp.zip

http状态码分类

  1. 消息类(1字头)
  2. 成功类(2字头)
  3. 重定向类(3字头)
  4. 请求错误类(4字头)
  5. 服务器错误类(5、6字头)

中途可能会穿插nginx自定义的http状态码,nginx状态码本身不属于http状态码了,只是在nginx内部自己定义的一套状态码,但是在nginx日志中,却经常出现

请求错误类(客户端错误)

400

400的英文含义400 Request Header Or Cookie Too Large,顾名思义,头信息或者Cookie信息太多了
复现这个状态码只需要添加够长的头信息或者Cookie信息即可,构造一个curl请求:

curl --header "Cookie:sidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidisidisisidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisidisisidisidisisidisidisisidisidisisidisidissidisisidisidisisidisi
? MySQL ?    2016-02-18 22:44:33    36247    1    2

前言

我们知道在MySQL中有3种类型可以表示实数,分别是float,double和decimal。关于如何合理得使用这三种类型,网上的答案也层出不穷。但是究竟该选择哪一种类型,好像并没有统一的答案,接下来,将通过一个例子来说明什么情况下选择float,什么情况下选择double,什么情况下选择decimal。相信对这个例子的剖析之后,你就会明白什么时候用什么样的类型

实数类型

举个例子

假如我们有一张表,用来存储用户的积分,表定义如下:

  1. CREATE TABLE `f` (
  2. `f1` float(10,2) DEFAULT NULL
  3. ) ENGINE=InnoDB DEFAULT CHARSET=utf-8

然后向这个表里插入131072.32的积分值,如下所示

  1. mysql> insert into f value (131072.32);
  2. Query OK, 1 row affected (0.00 sec)
  3. mysql> select * from f;
  4. +-----------+
  5. | f1 |
  6. +-----------+
  7. | 131072.31 |
  8. +-----------+
  9. 1 row in set (0.00 sec)

然后会惊奇的发现,这个用户的积分少了0.01,虽然这0.01的积分并不足于引起我们的注意,但是问题还是来了

  1. 丢失数据是否是正常现象?
  2. 为什么会少0.01,有没有可能少0.02,或者少1,少10甚至少100?
  3. 怎么样才能让我们的数据准确?

官方怎么看数据丢失

首先遇到问题,第一想到的就是官方找答案,我们翻阅官方文档,关于float和double有这样一段描述

For FLOAT, the SQL standard permits an optional specification of the precision (but not the range of the exponent) in bits following the keywordFLOAT in parentheses. MySQL also supports this optional precisio

4/4