0%

1. 介绍

CentOS 6.7 还仍然是python2.6.6,很多python的库都支持不好了。记录一下升级过程

2. 升级python

先升级Python,执行

1
2
3
4
5
6
7
8
wget https://www.python.org/ftp/python/2.7.9/Python-2.7.9.tgz
tar zxvf Python-2.7.9.tgz
cd Python-2.7.9
./configure
make all
make install
make clean
make distclean

3. 修改版本

目前的安装路径应该是/usr/local/bin/python2.7,顺便看下版本/usr/local/bin/python2.7 -V
然后查下当前的版本

1
python -V

我这里显示的是2.6.6
1
2
mv /usr/bin/python /usr/bin/python2.6 # 可能有的是python2.6.6
ln -s /usr/local/bin/python2.7 /usr/bin/python

现在再看下版本python -V,显示2.7.9。这样就可以运行python了

4. yum依赖修改

vim /usr/bin/yum

将头部的#!/usr/bin/python修改为#!/usr/bin/python2.6,有可能会改成2.6.6基于具体情况。

5. 安装setuptools和pip

1
2
wget http://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg 
sh setuptools-0.6c11-py2.7.egg

安装pip

1
2
3
4
wget http://pypi.python.org/packages/source/p/pip/pip-1.0.2.tar.gz 
tar zxf pip-1.0.2.tar.gz
cd pip-1.0.2
python setup.py install

现在,可以很方便的使用pip install安装东西,例如

1
2
pip install pelican
pip install Markdown

1. Gson

Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。可以将一个 JSON 字符串转成一个 Java 对象,或者反过来。

1.1 Gson转换出格式

Map的存储结构式Key/Value形式,Key 和 Value可以是普通类型,也可以是自己写的JavaBean,还可以是带有泛型的List.

1.1 具体例子

将Json转回为普通JavaBean对象时TypeToken的定义.JavaBean
Json转回为带泛型的对象List,并且List中的泛型对象有多种实体.LIST

2. JUnit

JUnit 是一个 Java 编程语言的单元测试框架。JUnit 在测试驱动的开发方面有很重要的发展,是起源于 JUnit 的一个统称为 xUnit 的单元测试框架之一。

JUnit 促进了“先测试后编码”的理念,强调建立测试数据的一段代码,可以先测试,然后再应用。这个方法就好比“测试一点,编码一点,测试一点,编码一点……”,增加了程序员的产量和程序的稳定性,可以减少程序员的压力和花费在排错上的时间。
详细的教程

1. TCP/IP参考模型

TCP/IP参考模型是一个抽象的分层模型,这个模型中,所有的TCP/IP系列网络协议都被归类到4个抽象的”层”中。每一抽象层创建在低一层提供的服务上,并且为高一层提供服务。

完成一些特定的任务需要众多的协议协同工作,这些协议分布在参考模型的不同层中的,因此有时称它们为一个协议栈。 TCP/IP参考模型为TCP/IP协议栈订身制作。其中IP协议只关心如何使得数据能够跨越本地网络边界的问题,而不关心如何利用传输媒体,数据如何传输。整个TCP/IP协议栈则负责解决数据如何通过许许多多个点对点通路(一个点对点通路,也称为一”跳”, 1 hop)顺利传输,由此不同的网络成员能够在许多”跳”的基础上创建相互的数据通路。

如想分析更普遍的网络通信问题,ISO的OSI模型也能起更好的帮助作用。

因特网协议族是一组实现支持因特网和大多数商业网络运行的协议栈的网络传输协议。它有时也被称为TCP/IP协议组,这个名称来源于其中两个最重要的协议:传输控制协议(TCP)和因特网协议(IP),它们也是最先定义的两个协议。 同许多其他协议一样网络传输协议也可以看作一个多层组合,每层解决数据传输中的一组问题并且向使用这些低层服务的高层提供定义好的服务。高层逻辑上与用户更为接近,所处理数据更为抽象,它们依赖于低层将数据转换成最终能够进行实体控制的形式。

网络传输协议能够大致匹配到一些厂商喜欢使用的固定7层的OSI模型。然而这些层并非都能够很好地与基于ip的网络对应(根据应用的设计和支持网络的不同它们确实是涉及到不同的层)并且一些人认为试图将因特网协议组对应到OSI会带来混淆而不是有所帮助。

2. 互联网控制消息协议 ICMP

网络控制消息协定(英文:Internet Control Message Protocol,ICMP)是网路协议族的核心协议之一。它用于TCP/IP网络中发送控制消息,提供可能发生在通信环境中的各种问题反馈,通过这些信息,令管理者可以对所发生的问题作出诊断,然后采取适当的措施解决。
ICMP依靠IP来完成它的任务,它是IP的主要部分。它与传输协议,如TCP和UDP显著不同:它一般不用于在两点间传输数据。它通常不由网络程序直接使用,除了ping和traceroute这两个特别的例子。 IPv4中的ICMP被称作ICMPv4,IPv6中的ICMP则被称作ICMPv6。

ICMP是在RFC 792中定义的互联网协议族之一。通常用于返回的错误信息或是分析路由。ICMP错误消息总是包括了源数据并返回给发送者。 ICMP错误消息的例子之一是TTL值过期。每个路由器在转发数据报的时候都会把IP包头中的TTL值减一。如果TTL值为0,“TTL在传输中过期”的消息将会回报给源地址。

每个ICMP消息都是直接封装在一个IP数据包中的,因此,和UDP一样,ICMP是不可靠的。

虽然ICMP是包含在IP数据包中的,但是对ICMP消息通常会特殊处理,会和一般IP数据包的处理不同,而不是作为IP的一个子协议来处理。在很多时候,需要去查看ICMP消息的内容,然后发送适当的错误消息到那个原来产生IP数据包的程序,即那个导致ICMP讯息被传送的IP数据包。

很多常用的工具是基于ICMP消息的。traceroute是通过发送包含有特殊的TTL的包,然后接收ICMP超时消息和目标不可达消息来实现的。ping则是用ICMP的”Echo request”(类别代码:8)和”Echo reply”(类别代码:0)消息来实现的。

3. TCP - 传输控制协议

TCP 用于从应用程序到网络的数据传输控制。
TCP 负责在数据传送之前将它们分割为IP包,然后在它们到达的时候将它们重组。

4. IP - 网际协议

IP 负责计算机之间的通信。
IP 负责在因特网上发送和接收数据包。

5. HTTP - 超文本传输协议

HTTP 负责 web 服务器与 web 浏览器之间的通信。
HTTP 用于从 web 客户端(浏览器)向 web 服务器发送请求,并从 web 服务器向 web 客户端返回内容(网页)。

6. HTTPS - 安全的 HTTP

HTTPS 负责在 web 服务器和 web 浏览器之间的安全通信。
作为有代表性的应用,HTTPS 会用于处理信用卡交易和其他的敏感数据。

7. SSL - 安全套接字层

SSL 协议用于为安全数据传输加密数据。

8. SMTP - 简易邮件传输协议

SMTP 用于电子邮件的传输。

9. MIME - 多用途因特网邮件扩展

MIME 协议使 SMTP 有能力通过TCP/IP网络传输多媒体文件,包括声音、视频和二进制数据。

10. IMAP - 因特网消息访问协议

IMAP 用于存储和取回电子邮件。

11. POP - 邮局协议

POP 用于从电子邮件服务器向个人电脑下载电子邮件。

12. FTP - 文件传输协议

FTP 负责计算机之间的文件传输。

13. NTP - 网络时间协议

NTP 用于在计算机之间同步时间(钟)。

14. DHCP - 动态主机配置协议

DHCP 用于向网络中的计算机分配动态 IP 地址。

15. SNMP - 简单网络管理协议

SNMP 用于计算机网络的管理。

16. LDAP - 轻量级的目录访问协议

LDAP 用于从因特网搜集关于用户和电子邮件地址的信息。

17. ICMP - 因特网消息控制协议

ICMP 负责网络中的错误处理。

18. ARP - Address Resolution Protocol

ARP - 用于通过 IP 来查找基于 IP 地址的计算机网卡的硬件地址。

19. RARP - Reverse Address Resolution Protocol

RARP 用于通过 IP 查找基于硬件地址的计算机网卡的 IP 地址。

20. BOOTP - Boot Protocol

BOOTP 用于从网络启动计算机。

21. PPTP - 点对点隧道协议

PPTP 用于私人网络之间的连接(隧道)。

22. Secure Shell - SSH

SSH为一项创建在应用层和传输层基础上的安全协议,为计算机上的Shell(壳层)提供安全的传输和使用环境。

SSH协议框架中最主要的部分是三个协议:

  • 传输层协议(The Transport Layer Protocol):传输层协议提供服务器认证,数据机密性,信息完整性等的支持。
  • 用户认证协议(The User Authentication Protocol):用户认证协议为服务器提供客户端的身份鉴别。
  • 连接协议(The Connection Protocol):连接协议将加密的信息隧道复用成若干个逻辑通道,提供给更高层的应用协议使用。
    同时还有为许多高层的网络安全应用协议提供扩展的支持。
    各种高层应用协议可以相对地独立于SSH基本体系之外,并依靠这个基本框架,通过连接协议使用SSH的安全机制。

23. DNS 域名系统

域名系统(英文:Domain Name System,缩写:DNS)是因特网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。DNS使用TCP和UDP端口53。当前,对于每一级域名长度的限制是63个字符,域名总长度则不能超过253个字符。
DNS系统中,常见的资源记录类型有:

  • 主机记录(A记录):RFC1035定义,A记录是用于名称解析的重要记录,它将特定的主机名映射到对应主机的IP地址上。
  • 别名记录(CNAME记录):RFC1035定义,CNAME记录用于将某个别名指向到某个A记录上,这样就不需要再为某个新名字另外创建一条新的A记录。
  • IPv6主机记录(AAAA记录): RFC 3596定义,与A记录对应,用于将特定的主机名映射到一个主机的IPv6地址。
  • 服务位置记录(SRV记录): RFC 2782定义,用于定义提供特定服务的服务器的位置,如主机(hostname),端口(port number)等。
  • NAPTR记录:RFC 3403定义,它提供了正则表达式方式去映射一个域名。NAPTR记录非常著名的一个应用是用于ENUM查询。

1. 下载

下载mongodb的windows版本,有32位和64位版本,根据系统情况下载,下载地址:http://www.mongodb.org/downloads
按照步骤进行安装。
默认是在C:\Program Files\MongoDB\Server\3.2\bin,我的是64位的。
Path添加C:\Program Files\MongoDB\Server\3.2\bin这行。这样就可以命令行启动了

2. 启动

运行mongodb服务,—dbpath指的是数据库地址

mongod.exe —dbpath D:/mongodb/data/db

启动成功后能够看到是数据库端口和Web端口,默认分别是27017和28017,在浏览器中打开http://localhost:28017,可以看到其相关的一些信息。

可以通过添加参数—port的方式,来修改数据库端口:

mongod.exe —port 10001 —dbpath D:/mongodb/data/db

上面这个是服务,还需要再开一个终端进行连接数据库

mongo

就可以连接上mongodb的服务

3. 自启动加入windows服务

这样每次启动MongoDB很不方便,我们可以像安装的MySQL一样,把它作为Windows服务,这样就方便多了。
安装MongoDB的windows服务的方法为是在相应目录下创建logs目录,然后在CMD命令行输入

mongod —logpath D:/Work/Mongodb/logs/mongodb.log —logappend —dbpath D:/Work/Mongodb/data/db —directoryperdb —serviceName MongoDB —install

注意CMD要是管理员模式
数据文件目录:/data/db,并且参数—directoryperdb说明每个DB都会新建一个目录;
Windows服务的名称:MongoDB;

以后就可以在cmd下用命令net start MongoDB和net stop MongoDB来启动和停止MongoDB了,也可以在本地服务中看到

介绍

Zookeeper是一个分布式开源框架,提供了协调分布式应用的基本服务,它向外部应用暴露一组通用服务——分布式同步(Distributed Synchronization)、命名服务(Naming Service)、集群维护(Group Maintenance)等,简化分布式应用协调及其管理的难度,提供高性能的分布式服务。ZooKeeper本身可以以单机模式安装运行,不过它的长处在于通过分布式ZooKeeper集群(一个Leader,多个Follower),基于一定的策略来保证ZooKeeper集群的稳定性和可用性,从而实现分布式应用的可靠性。

在分布式应用中,由于工程师不能很好地使用锁机制,以及基于消息的协调机制不适合在某些应用中使用,因此需要有一种可靠的、可扩展的、分布式的、可配置的协调机制来统一系统的状态。Zookeeper的目的就在于此。

数据存储模型

  • Persistent Nodes: 永久有效地节点,除非client显式的删除,否则一直存在
  • Ephemeral Nodes: 临时节点,仅在创建该节点client保持连接期间有效,一旦连接丢失,zookeeper会自动删除该节点
  • Sequence Nodes: 顺序节点,client申请创建该节点时,zk会自动在节点路径末尾添加递增序号,这种类型是实现分布式锁,分布式queue等特殊功能的关键

典型使用场景

分布式锁

分布式锁,主要得益于ZooKeeper保证数据的强一致性,即ZooKeeper集群中任意节点(一个server)上系统znode的数据一定相同。

锁服务可以分为两类:

  • 保持独占锁:所有试图来获取这个锁的客户端,最终只有一个可以成功获得这把锁。通常的做法是把ZooKeeper上的一个znode看做是一把锁,通过create znode的方式来实现。所有客户端都去创建/distribute_lock节点,最终成功创建的那个客户端也即拥有了这把锁。
  • 控制时序锁:所有试图来获取这个锁的客户端,最终都是会被安排执行,只是有个全局时序了。与保持独占锁的做法类似,不同点是/distribute_lock已经预先存在,客户端在它下面创建临时有序节点(可以通过节点控制属性控制:CreateMode.EPHEMERAL_SEQUENTIAL来指定)。zk的父节点(/distribute_lock)维持一份sequence,保证子节点创建的时序性,从而形成每个客户端的全局时序。

发布与订阅

发布与订阅即所谓的配置管理,顾名思义就是将数据发布到ZooKeeper节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如:全局的配置信息、地址列表等。

  • 索引信息和集群中机器节点状态放在ZooKeeper的一些指定节点,供各个客户端订阅使用。
  • 系统日志(经处理后)存储,这些日志通常2-3天后清除。
  • 应用中用到的一些配置信息集中管理,在应用启动的时候主动来获取一次,并在节点上注册一个Watcher,以后每次配置有更新,实时通知到应用,获取最新的配置信息。
  • 业务逻辑中需要用到的一些全局变量,比如一些消息中间件的消息队列通常有个offset,这个offset存放在ZooKeeper上,这样集群中每个发送者都能知道当前的发送进度。
  • 系统中有些信息需要动态获取,并且还会存在人工手动去修改这个信息。以前通常是暴露出接口,例如JMX接口,有了ZooKeeper后,只要将这些信息存放到ZooKeeper节点上即可。

分布通知/协调

ZooKeeper中特有的watcher注册于异步通知机制,能够很好的实现分布式环境下不同系统之间的通知与协调,实现对数据变更的实时处理。使用方法通常是不同系统都对ZooKeeper上同一个znode进行注册,监听znode的变化(包括znode本身内容及子节点内容),其中一个系统update了znode,那么另一个系统能够收到通知,并做出相应处理。
使用ZooKeeper来进行分布式通知和协调能够大大降低系统之间的耦合。

  • 心跳检测机制:检测系统和被测系统之间并不直接关联起来,而是通过ZooKeeper上某个节点关联,大大减少系统耦合。
  • 系统调度模式:某系统有控制台和推送系统两部分组成,控制台的职责是控制推送系统进行相应的推送工作。管理人员在控制台做的一些操作,实际上是修改了ZooKeeper上某些节点的状态,而ZooKeeper就把这些变化通知给它们注册watcher的客户端,即推送系统,于是,做出相应的推送任务。
  • 工作汇报模式:一些类似于任务分发系统,子任务启动后,到zk来注册一个临时节点,并定时将自己的进度进行汇报(将进度写回这个临时节点),这样任务管理者就能够实时指导任务进度。

集群管理

  • 集群机器监控:这通常用于那种对集群中机器状态、机器在线率有较高要求的场景,能够快速对集群中机器变化做出响应。这样的场景中,往往有一个监控系统,实时监测集群机器是否存活。利用ZooKeeper,可以实现另一种集群机器存活性监控系统:
    • 客户端在节点x上注册watcher,如果x的子节点发生变化,会通知该客户端。
    • 创建EPHEMERAL类型的节点,一旦客户端和服务器的会话结束或过期,该节点就会消失。
  • Master选举:在分布式环境中,相同的业务应用分布在不同的机器上,有些业务逻辑(例如一些耗时的计算、网络I/O处理),往往需要让整个集群中的某一台机器进行执行,其余机器可以共享这个结果,这样可以减少重复劳动、提高性能。利用ZooKeeper的强一致性,能够保证在分布式高并发情况下节点创建的全局唯一性,即:同时有多个客户端请求创建/currentMaster节点,最终一定只有一个客户端请求能够创建成功。利用这个特性,就能很轻易的在分布式环境中进行集群选取了。另外,这种场景演化一下,就是动态Master选举。

集群搭建

其中ZooKeeper版本为3.4.8,安装目录于/usr/local/program/。ZooKeeper下载完成后的文件就是编译好的,可以直接使用的。

下载安装

1
2
3
wget http://mirror.nus.edu.sg/apache/zookeeper/zookeeper-3.4.8/zookeeper-3.4.8.tar.gz
tar -zxvf zookeeper-3.4.8.tar.gz -C /usr/local/program/
ln -s /usr/local/program/zookeeper-3.4.8 /usr/local/program/zookeeper

config环境配置

首先进入conf目录

1
2
cd conf/
cp zoo_sample.cfg zoo.cfg

修改zoo.cfg文件

1
2
3
4
5
6
7
8
dataDir=/usr/local/program/zookeeper/data
dataLogDir=/usr/local/program/zookeeper/logs
clientPort=2181
tickTime=2000
initLimit=5
syncLimit=2
server.1=node4:2888:3888
server.2=node5:2888:3888

因为我的测试环境就部署了两台server,所以就用node4和node5,如果增加server就增加几行。
node4是修改host之后的。把ip的对应关系要先修改好。
两个server是一样的配置方法。

修改server的myid

在node5的修改为:

mkdir -p /usr/local/program/zookeeper/data/ echo 2 > /usr/local/program/zookeeper/data/myid

在node4的修改为:

mkdir -p /usr/local/program/zookeeper/data/ echo 1 > /usr/local/program/zookeeper/data/myid

启动ZooKeeper集群

在bin文件夹下运行如下指令。两台server都需要运行这个命令。看到STARTED表示运行成功。

./zkServer.sh start

然后通过bin文件夹下的zkServer.sh

./zkServer.sh status

通过上面状态查询结果可见,node4是集群的Leader,另一个结点是Follower。

停止ZooKeeper集群

在bin文件夹下运行

./zkServer.sh stop

参考

otter4使用介绍

深入理解otter

之前一直用WordPress建博客,但是现在发现这个太重了,所以考虑迁移到hexo,一个静态的建站工具。下面是我的配置的指南

在本地简历建立hexo博客

安装 Hexo

1
npm install -g hexo-cli

配置 Hexo

到想要放博客的文件夹

1
2
hexo init
npm install

生成目录如下
1
2
3
4
5
6
7
8
.
├── _config.yml #配置文件
├── package.json #应用程序数据
├── scaffolds
├── source #网站内容
| ├── _drafts #草稿
| └── _posts #文章
└── themes #主题

下载设置主题

我使用的hexo主题是litten

下载主题:git clone https://github.com/litten/hexo-theme-yilia.git yilia

启用主题:clone完成后,打开 站点配置文件_config.yml,找到 theme 字段,并将其值更改为下载的主题的文件夹名字。不是主题的名字,是你下载下来的文件夹名字。文件夹要放在theme下面。
然后发布一下就可以了。

hexo常用命令

如下是经常使用的命令

1
2
3
4
5
6
hexo new "postName" #新建文章
hexo new page "pageName" #新建页面
hexo generate #生成静态页面至public目录
hexo server #开启预览访问端口(默认端口4000,'ctrl + c'关闭server)
hexo deploy #将.deploy目录部署到GitHub
hexo clean #清除database和public文件夹

发布命令
1
hexo d -g #发布到public,并生成github pages

WordPress导出文章

WordPress里面有个工具,然后导出。我当时导出的时候防止出问题,只导出了文章,变成一个xml文件。

安装插件导入

首先安装 hexo-migrator-wordpress 插件:

1
2
npm install hexo-migrator-wordpress --save
hexo migrate wordpress <source>

source 是 Wordpress 导出文件的存放路径。之后就导入到_posts 目录了!

解决导出的各种问题

这样导出出来的md,中文显示是有问题的,然后还有各种格式不匹配根本没办法用,一直会报错。
具体可以参考hexo—wordpress-import的代码,我是用Windows的生成文章的。所以用这个来格式化了一下,然后再生成文章。

插件

多说 评论插件

这个在litten的主题里是已经集成了,但是需要你在多说创建账号和网站,需要修改配置文件。
themes/yilia/layout/_partial/post/duoshuo.ejs这个文件,主要是要theme.duoshuo这个改成你在多说的名字。具体是什么参考多说上面的介绍。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div class="duoshuo">
<!-- 多说评论框 start -->
<div class="ds-thread" data-thread-key="<%=key%>" data-title="<%=title%>" data-url="<%=url%>"></div>
<!-- 多说评论框 end -->
<!-- 多说公共JS代码 start (一个网页只需插入一次) -->
<script type="text/javascript">
var duoshuoQuery = {short_name:"<%=theme.duoshuo%>"};
(function() {
var ds = document.createElement('script');
ds.type = 'text/javascript';ds.async = true;
ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
ds.charset = 'UTF-8';
(document.getElementsByTagName('head')[0]
|| document.getElementsByTagName('body')[0]).appendChild(ds);
})();
</script>
<!-- 多说公共JS代码 end -->
</div>

这个配置文件的地址在themes/yilia/_config.yml这个里面的duoshuo: 变成你的多说工具里面的short_name就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 多说评论框 start -->
<div class="ds-thread" data-thread-key="请将此处替换成文章在你的站点中的ID" data-title="请替换成文章的标题" data-url="请替换成文章的网址"></div>
<!-- 多说评论框 end -->
<!-- 多说公共JS代码 start (一个网页只需插入一次) -->
<script type="text/javascript">
var duoshuoQuery = {short_name:"lichblog"};
(function() {
var ds = document.createElement('script');
ds.type = 'text/javascript';ds.async = true;
ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
ds.charset = 'UTF-8';
(document.getElementsByTagName('head')[0]
|| document.getElementsByTagName('body')[0]).appendChild(ds);
})();
</script>
<!-- 多说公共JS代码 end -->

git同步文章

因为我使用的hostker,可以直接通过git发布。
所以把在hexo主目录下直接git clone 你的git的地址 public。
这样会创建public文件夹为同步目录,注意在这之前要hexo clean一下。
然后再hexo d -g在public里面生成相应的文件

静态页面的设置

如果有静态页面比如CV,或者一些简单的页面的话是不能直接放到public文件夹下面的,每次发布会被删掉。
解决策略就是放到source文件夹。

  1. 如果你需要hexo当前主题的渲染,那就当在主目录的source文件夹下面。
  2. 如果是纯粹的静态页面,放在themes/你的主题名称/source文件夹下面。

这样做之后放在source下面的文件会在生成的时候直接放到public里面。访问路径就是以public目录为域名。
比如你的静态页面放在themes/你的主题名称/source/abc/index.html那访问路径就是:域名/abc/index.html这样的。

域名和 DNS 解析

主机是在hostker上买的,一个应用貌似一天只要1分钱,如果是用git进行同步的静态页面,超级便宜。
域名是在万网上早买好的,然后万网里有地方可以设置解析的地方,我的是cname,在hostker上设置添加域名然后把地址贴到万网上就可以等待生效了,一般一两分钟就可以解析成功。

CDN设置

使用的是七牛的云存储服务。主要是为了图片考虑,图片不放在服务器上,因为挺占用大小的,每次同步都需要很大的空间。
直接在七牛上建立账号,添加应用,然后使用公开的链接放图片,写md的时候直接加进去就可以了。

Windows 安装Git

在Windows上安装Git
实话实说,Windows是最烂的开发平台,如果不是开发Windows游戏或者在IE里调试页面,一般不推荐用Windows。不过,既然已经上了微软的贼船,也是有办法安装Git的。

Windows下要使用很多Linux/Unix的工具时,需要Cygwin这样的模拟环境,Git也一样。Cygwin的安装和配置都比较复杂,就不建议你折腾了。不过,有高人已经把模拟环境和Git都打包好了,名叫msysgit,只需要下载一个单独的exe安装程序,其他什么也不用装,绝对好用。

msysgit是Windows版的Git,从http://msysgit.github.io/下载,然后按默认选项安装即可。

安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明Git安装成功!

1
install-git-on-windows

安装完成后,还需要最后一步设置,在命令行输入:

1
2
$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"

因为Git是分布式版本控制系统,所以,每个机器都必须自报家门:你的名字和Email地址。你也许会担心,如果有人故意冒充别人怎么办?这个不必担心,首先我们相信大家都是善良无知的群众,其次,真的有冒充的也是有办法可查的。

注意git config命令的—global参数,用了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然也可以对某个仓库指定不同的用户名和Email地址。

创建版本库

什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

所以,创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录。

如果你使用Windows系统,为了避免遇到各种莫名其妙的问题,请确保目录名(包括父目录)不包含中文。

第二步,通过git init命令把这个目录变成Git可以管理的仓库:

1
2
$ git init
Initialized empty Git repository in /Users/michael/learngit/.git/

瞬间Git就把仓库建好了,而且告诉你是一个空的仓库(empty Git repository),可以发现当前目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。

也不一定必须在空目录下创建Git仓库,选择一个已经有东西的目录也是可以的。不过,不建议你使用自己正在开发的项目来学习Git,否则造成的一切后果概不负责。

把文件添加到版本库

首先这里再明确一下,所有的版本控制系统,其实只能跟踪文本文件的改动,比如TXT文件,网页,所有的程序代码等等,Git也不例外。版本控制系统可以告诉你每次的改动,比如在第5行加了一个单词“Linux”,在第8行删了一个单词“Windows”。而图片、视频这些二进制文件,虽然也能由版本控制系统管理,但没法跟踪文件的变化,只能把二进制文件每次改动串起来,也就是只知道图片从100KB改成了120KB,但到底改了啥,版本控制系统不知道,也没法知道。

不幸的是,Microsoft的Word格式是二进制格式,因此,版本控制系统是没法跟踪Word文件的改动的,前面我们举的例子只是为了演示,如果要真正使用版本控制系统,就要以纯文本方式编写文件。

因为文本是有编码的,比如中文有常用的GBK编码,日文有Shift_JIS编码,如果没有历史遗留问题,强烈建议使用标准的UTF-8编码,所有语言使用同一种编码,既没有冲突,又被所有平台所支持。

使用Windows的童鞋要特别注意:

千万不要使用Windows自带的记事本编辑任何文本文件。原因是Microsoft开发记事本的团队使用了一个非常弱智的行为来保存UTF-8编码的文件,他们自作聪明地在每个文件开头添加了0xefbbbf(十六进制)的字符,你会遇到很多不可思议的问题,比如,网页第一行可能会显示一个“?”,明明正确的程序一编译就报语法错误,等等,都是由记事本的弱智行为带来的。建议你下载Notepad++或者sublime代替记事本,不但功能强大,而且免费!记得把Notepad++的默认编码设置为UTF-8 without BOM即可:

言归正传,现在我们编写一个readme.txt文件,内容如下:

1
2
Git is a version control system.
Git is free software.

一定要放到learngit目录下(子目录也行),因为这是一个Git仓库,放到其他地方Git再厉害也找不到这个文件。

和把大象放到冰箱需要3步相比,把一个文件放到Git仓库只需要两步。

第一步,用命令git add告诉Git,把文件添加到仓库:

1
$ git add readme.txt

执行上面的命令,没有任何显示,这就对了,Unix的哲学是“没有消息就是好消息”,说明添加成功。

第二步,用命令git commit告诉Git,把文件提交到仓库:

1
2
3
4
$ git commit -m "wrote a readme file"
[master (root-commit) cb926e7] wrote a readme file
1 file changed, 2 insertions(+)
create mode 100644 readme.txt

简单解释一下git commit命令,-m后面输入的是本次提交的说明,可以输入任意内容,当然最好是有意义的,这样你就能从历史记录里方便地找到改动记录。

嫌麻烦不想输入-m “xxx”行不行?确实有办法可以这么干,但是强烈不建议你这么干,因为输入说明对自己对别人阅读都很重要。

git commit命令执行成功后会告诉你,1个文件被改动(我们新添加的readme.txt文件),插入了两行内容(readme.txt有两行内容)。

为什么Git添加文件需要add,commit一共两步呢?因为commit可以一次提交很多文件,所以你可以多次add不同的文件,比如:

1
2
3
4
$ git add file1.txt
$ git add file2.txt
$ git add file3.txt
$ git commit -m "add 3 files."

小结

现在总结一下今天学的两点内容:

初始化一个Git仓库,使用git init命令。

添加文件到Git仓库,分两步:

第一步,使用命令git add ,注意,可反复多次使用,添加多个文件;

第二步,使用命令git commit,完成。

添加远程库

现在的情景是,你已经在本地创建了一个Git仓库后,又想在GitHub创建一个Git仓库,并且让这两个仓库进行远程同步,这样,GitHub上的仓库既可以作为备份,又可以让其他人通过该仓库来协作,真是一举多得。

首先,登陆GitHub,然后,在右上角找到“Create a new repo”按钮,创建一个新的仓库。

在Repository name填入learngit,其他保持默认设置,点击“Create repository”按钮,就成功地创建了一个新的Git仓库。

目前,在GitHub上的这个learngit仓库还是空的,GitHub告诉我们,可以从这个仓库克隆出新的仓库,也可以把一个已有的本地仓库与之关联,然后,把本地仓库的内容推送到GitHub仓库。

现在,我们根据GitHub的提示,在本地的learngit仓库下运行命令:

1
$ git remote add origin [email protected]:michaelliao/learngit.git

请千万注意,把上面的michaelliao替换成你自己的GitHub账户名,否则,你在本地关联的就是我的远程库,关联没有问题,但是你以后推送是推不上去的,因为你的SSH Key公钥不在我的账户列表中。

添加后,远程库的名字就是origin,这是Git默认的叫法,也可以改成别的,但是origin这个名字一看就知道是远程库。

下一步,就可以把本地库的所有内容推送到远程库上:

1
2
3
4
5
6
7
8
9
$ git push -u origin master
Counting objects: 19, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (19/19), done.
Writing objects: 100% (19/19), 13.73 KiB, done.
Total 23 (delta 6), reused 0 (delta 0)
To [email protected]:michaelliao/learngit.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.

把本地库的内容推送到远程,用git push命令,实际上是把当前分支master推送到远程。

由于远程库是空的,我们第一次推送master分支时,加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。
推送成功后,可以立刻在GitHub页面中看到远程库的内容已经和本地一模一样。

从现在起,只要本地作了提交,就可以通过命令:

1
$ git push origin master

把本地master分支的最新修改推送至GitHub,现在,你就拥有了真正的分布式版本库!

小结

要关联一个远程库,使用命令git remote add origin git@server-name:path/repo-name.git;

关联后,使用命令git push -u origin master第一次推送master分支的所有内容;

此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;

分布式版本系统的最大好处之一是在本地工作完全不需要考虑远程库的存在,也就是有没有联网都可以正常工作,而SVN在没有联网的时候是拒绝干活的!当有网络的时候,再把本地提交推送一下就完成了同步,真是太方便了!

创建删除分支

Git鼓励大量使用分支:

1
2
3
4
5
6
7
8
9
10
11
查看分支:git branch

创建分支:git branch <name>

切换分支:git checkout <name>

创建+切换分支:git checkout -b <name>

合并某分支到当前分支:git merge <name>

删除分支:git branch -d <name>

多人协作

当你从远程仓库克隆时,实际上Git自动把本地的master分支和远程的master分支对应起来了,并且,远程仓库的默认名称是origin。

要查看远程库的信息,用git remote:

1
2
$ git remote
origin

或者,用git remote -v显示更详细的信息:
1
2
3
$ git remote -v
origin [email protected]:michaelliao/learngit.git (fetch)
origin [email protected]:michaelliao/learngit.git (push)

上面显示了可以抓取和推送的origin的地址。如果没有推送权限,就看不到push的地址。

推送分支

推送分支,就是把该分支上的所有本地提交推送到远程库。推送时,要指定本地分支,这样,Git就会把该分支推送到远程库对应的远程分支上:

1
$ git push origin master

如果要推送其他分支,比如dev,就改成:

1
$ git push origin dev

但是,并不是一定要把本地分支往远程推送,那么,哪些分支需要推送,哪些不需要呢?

master分支是主分支,因此要时刻与远程同步;

dev分支是开发分支,团队所有成员都需要在上面工作,所以也需要与远程同步;

bug分支只用于在本地修复bug,就没必要推到远程了,除非老板要看看你每周到底修复了几个bug;

feature分支是否推到远程,取决于你是否和你的小伙伴合作在上面开发。

总之,就是在Git中,分支完全可以在本地自己藏着玩,是否推送,视你的心情而定!

抓取分支

多人协作时,大家都会往master和dev分支上推送各自的修改。

现在,模拟一个你的小伙伴,可以在另一台电脑(注意要把SSH Key添加到GitHub)或者同一台电脑的另一个目录下克隆:

1
2
3
4
5
6
7
$ git clone [email protected]:michaelliao/learngit.git
Cloning into 'learngit'...
remote: Counting objects: 46, done.
remote: Compressing objects: 100% (26/26), done.
remote: Total 46 (delta 16), reused 45 (delta 15)
Receiving objects: 100% (46/46), 15.69 KiB | 6 KiB/s, done.
Resolving deltas: 100% (16/16), done.

当你的小伙伴从远程库clone时,默认情况下,你的小伙伴只能看到本地的master分支。不信可以用git branch命令看看:
1
2
$ git branch
* master

现在,你的小伙伴要在dev分支上开发,就必须创建远程origin的dev分支到本地,于是他用这个命令创建本地dev分支:
1
$ git checkout -b dev origin/dev

现在,他就可以在dev上继续修改,然后,时不时地把dev分支push到远程:
1
2
3
4
5
6
7
8
9
10
11
$ git commit -m "add /usr/bin/env"
[dev 291bea8] add /usr/bin/env
1 file changed, 1 insertion(+)
$ git push origin dev
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 349 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To [email protected]:michaelliao/learngit.git
fc38031..291bea8 dev -> dev

你的小伙伴已经向origin/dev分支推送了他的提交,而碰巧你也对同样的文件作了修改,并试图推送:
1
2
3
4
5
6
7
8
9
10
11
12
$ git add hello.py 
$ git commit -m "add coding: utf-8"
[dev bd6ae48] add coding: utf-8
1 file changed, 1 insertion(+)
$ git push origin dev
To [email protected]:michaelliao/learngit.git
! [rejected] dev -> dev (non-fast-forward)
error: failed to push some refs to '[email protected]:michaelliao/learngit.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

推送失败,因为你的小伙伴的最新提交和你试图推送的提交有冲突,解决办法也很简单,Git已经提示我们,先用git pull把最新的提交从origin/dev抓下来,然后,在本地合并,解决冲突,再推送:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ git pull
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0)
Unpacking objects: 100% (3/3), done.
From github.com:michaelliao/learngit
fc38031..291bea8 dev -> origin/dev
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details

git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

git branch --set-upstream dev origin/<branch>


git pull也失败了,原因是没有指定本地dev分支与远程origin/dev分支的链接,根据提示,设置dev和origin/dev的链接:
1
2
$ git branch --set-upstream dev origin/dev
Branch dev set up to track remote branch dev from origin.

再pull:
1
2
3
4
$ git pull
Auto-merging hello.py
CONFLICT (content): Merge conflict in hello.py
Automatic merge failed; fix conflicts and then commit the result.

这回git pull成功,但是合并有冲突,需要手动解决,解决的方法和分支管理中的解决冲突完全一样。解决后,提交,再push:
1
2
3
4
5
6
7
8
9
10
$ git commit -m "merge & fix hello.py"
[dev adca45d] merge & fix hello.py
$ git push origin dev
Counting objects: 10, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 747 bytes, done.
Total 6 (delta 0), reused 0 (delta 0)
To [email protected]:michaelliao/learngit.git
291bea8..adca45d dev -> dev

因此,多人协作的工作模式通常是这样:

首先,可以试图用git push origin branch-name推送自己的修改;

如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并;

如果合并有冲突,则解决冲突,并在本地提交;

没有冲突或者解决掉冲突后,再用git push origin branch-name推送就能成功!

如果git pull提示“no tracking information”,则说明本地分支和远程分支的链接关系没有创建,用命令git branch —set-upstream branch-name origin/branch-name。

这就是多人协作的工作模式,一旦熟悉了,就非常简单。

小结

查看远程库信息,使用git remote -v;

本地新建的分支如果不推送到远程,对其他人就是不可见的;

从本地推送分支,使用git push origin branch-name,如果推送失败,先用git pull抓取远程的新提交;

在本地创建和远程分支对应的分支,使用git checkout -b branch-name origin/branch-name,本地和远程分支的名称最好一致;

建立本地分支和远程分支的关联,使用git branch —set-upstream branch-name origin/branch-name;

从远程抓取分支,使用git pull,如果有冲突,要先处理冲突。

安装完XAMPP后,MySQL的默认账号为root,密码为空。
如果要连接数据库,记得

user = 'root';
password = '';

如果需要修改,可以直接在phpmyadmin里面修改:
1. 游览器打开 http://localhost/phpmyadmin,进入后点击'用户账户
2. 点击用户为root,主机为localhost的修改权限,在上面会有一个修改密码点击。
3. 输入新的密码。点击执行。

这样mysql密码已经更新,但是phpmyadmin的并没有。需要修改它的配置。在XAMPP上点击explore,进去XAMPP\phpMyAdmin\config.inc.php。修改

$cfg['Servers'][$i]['password'] = '<相应密码>';

目前所选用的是当前的最新版本Vagrant 1.7.2,VirtualBox 使用的是 VirtualBox 4.3.28。记录一下自己在windows配置时的情况

准备工作

  1. 首先下载Vagrantvirtual box,安装vagrant需要重启系统。然后就可以在cmd下使用vagrant的命令了。
  2. 准备下载box(有两种主要下载方法)
  • Vagrant cloud 这里面是hashicorp的一个在线box平台。如果你需要使用这上面的box进行下载配置,找到下面任意一个box进行选择,比如Ubuntu trusty64这是下载最多的。把cmd进入到你的工作目录。运行下面的命令:
vagrant init ubuntu/trusty64
vagrant up --provider virtualbox
  • Vagrant.es,这里面的box你可以通过下载然后把box文件放在你的当前工作目录,执行以下命令:
vagrant box add base *.box
vagrant init
  • base 表示指定默认的box,也可以为box指定名称,比如 Ubuntu ,使用base时,之后可以直接使用 vagrant init 进行初始化,如果自行指定名称,则初始化的时候需要指定box的名称。*.box 是box对应的文件名,这里可以是本地保存box的路径(未加则是当前目录),也可以是可以下载box的网址,如果是网址的话,Vagrant会自动启动下载。
  • 最后一步,运行Vagrant中的虚拟机。
vagrant up

注意事项

  1. 如果你目前用户名是中文用户名的话(也就是User/用户名),由于vagrant会调用用户目录下的文件,所以这个用户名必须是英文的否则init过程中会出现编码错误。
  2. 如果仍然出现问题,需要在Vagrant安装目录下的bin的配置文件里面修改编码。
  3. 启动之后可以使用127.0.0.1:2222通过ssh连上虚拟机,没必要使用vagrant ssh。
  4. 登录过程中账号密码都是vagrant,包括su。

配置工作

Vagrant网络基本有三种模式

都在此虚拟机的Vagrantfile进行修改就行,配置文件还是写的很详细的。

  • 端口映射:就是将虚拟机中的端口映射到宿主机对应的端口直接使用。guest: 80 表示虚拟机中的80端口,host: 8080 表示映射到宿主机的8080端口。
config.vm.network :forwarded_port, guest: 80, host: 8080
  • private模式:如果需要自己自由的访问虚拟机,但是别人不需要访问虚拟机,可以使用private_network,并为虚拟机设置IP。192.168.1.111 表示虚拟机的IP,多台虚拟机的话需要互相访问的话,设置在相同网段即可。
config.vm.network :private_network, ip: "192.168.1.111"
  • public模式:如果需要将虚拟机作为当前局域网中的一台计算机。这个配置和上面的配置主要是用来多个虚拟机然后搭建分布式网络系统,模拟网络上多台设备,具体也有教程,参考教程
config.vm.network :public_network

文件映射

本地开发,虚拟机运行。所以这里就需要使用文件映射功能,将本地的目录文件映射到虚拟机的对应目录。
默认情况下,当前的工作目录,会被映射到虚拟机的 /vagrant 目录,当前目录下的文件可以直接在 /vagrant 下进行访问。
主要两种方法,一个软链接(每次开机都要输一遍),一个修改配置文件一步到位。

  • 每次ssh到虚拟机输入:
ln -fs /vagrant/wwwroot /var/www
  • 找到配置文件的相应部分,进行修改。前面参数本地路径,可以相对也可以绝对比如修改为:“d:/data”。后面参数表示虚拟机对应映射目录
config.vm.synced_folder "data/", "/var/data"

Vagrant 主要命令

vagrant box add 添加box的操作
vagrant init 初始化box的操作
vagrant up 启动虚拟机的操作
vagrant ssh 登录拟机的操作
vagrant box list 显示当前已经添加的box列表
vagrant box remove 删除相应的box
vagrant destroy 停止当前正在运行的虚拟机并销毁所有创建的资源
vagrant halt 关机
vagrant package 打包命令,可以把当前的运行的虚拟机环境进行打包
vagrant plugin 用于安装卸载插件
vagrant provision 通常情况下Box只做最基本的设置,而不是设置好所有的环境,因此Vagrant通常使用Chef或者Puppet来做进一步的环境搭建。那么Chef或者Puppet称为provisioning,而该命令就是指定开启相应的provisioning。按照Vagrant作者的说法,所谓的provisioning就是"The problem of installing software on a booted system"的意思。除了Chef和Puppet这些主流的配置管理工具之外,我们还可以使用Shell来编写安装脚本。例如: vagrant provision --provision-with chef
vagrant reload 重新启动虚拟机,主要用于重新载入配置文件
vagrant resume 恢复前面被挂起的状态
vagrant ssh-config 输出用于ssh连接的一些信息
vagrant status 获取当前虚拟机的状态

更多参考信息docs

终于还是做出了这样的决定,在此立证,务必做到以下:

I do not forgive
I do not forget