#
什么是spring-loaded?
spring-loaded是一個(gè)對于jvm代理運(yùn)行時(shí)期改變類文件的重載(重新加載),它轉(zhuǎn)換類loadtime讓他們服從后重新加載。不像“熱代碼替換”只允許一次簡單的改變JVM運(yùn)行(例如更改方法體)spring-loaded允許您添加/修改/刪除/字段/方法構(gòu)造函數(shù)。注釋類型/方法/字段/構(gòu)造函數(shù)也可以修改和可以添加/刪除/修改值的枚舉類型。
有什么好處?
開發(fā)測試階段:能夠在啟動(dòng)后動(dòng)態(tài)更改代碼調(diào)試,無需重啟減少切換debug時(shí)間(ps:對于eclipse而言,在debug時(shí)期只能做到動(dòng)態(tài)更新方法體不能增加)
對于線上測試發(fā)布階段: 能夠在出現(xiàn)問題后直接替換class文件而不重啟應(yīng)用(ps:對于外部提供的服務(wù)jar形式同樣能做到)
怎么使用?
項(xiàng)目地址
https://github.com/spring-projects/spring-loaded
第一步:下載文件
http://repo.spring.io/release/org/springframework/springloaded/1.2.5.RELEASE/springloaded-1.2.5.RELEASE.jar第二步:配置jvm啟動(dòng)參數(shù)
eclipse
eclipse:run as --> run configurations --> arguments -->> VM arguments
-javaagent:E:\repository\org\springframework\spring-load\springloaded-1.2.5.RELEASE.jar
-noverify -Dspringloaded=verbose
詳細(xì)描述:
-javaagent: 配置java代理使用下載后的jar包路徑
-noverify: 禁用字節(jié)碼驗(yàn)證
-Dspringloaded=verbose 顯示springloaded時(shí)的詳細(xì)信息

java命令啟動(dòng)
java -javaagent:E:\repository\org\springframework\spring-load\springloaded-1.2.5.RELEASE.jar -noverify Test 類似
java jar包動(dòng)態(tài)替換
1.打成runnable Jar
2.命令啟動(dòng):
java -javaagent:E:\repository\org\springframework\spring-load\springloaded-1.2.5.RELEASE.jar -noverify -Dspringloaded=watchJars=main.jar main.jar
/** * 類Test.java的實(shí)現(xiàn)描述:TODO 類實(shí)現(xiàn)描述 * @author Administrator 2016年7月4日 下午4:55:59 */ public class Test { public static void main(String[] args) throws InterruptedException { while(true) { try { println(); Thread.sleep(1000); } catch (Throwable e) { e.printStackTrace(); } } } public static void println() { System.out.println("112222221222222"); } }
改變?yōu)?/p>
/** * 類Test.java的實(shí)現(xiàn)描述:TODO 類實(shí)現(xiàn)描述 * @author Administrator 2016年7月4日 下午4:55:59 */ public class Test { public static void main(String[] args) throws InterruptedException { while(true) { try { println(); Thread.sleep(1000); } catch (Throwable e) { e.printStackTrace(); } } } public static void println() { System.out.println("test replace jar"); } }
3.重新打包替換
PS:實(shí)測在window下無用 手上無linux機(jī)器待測試
1
Spring Cloud 為開發(fā)者提供了在分布式系統(tǒng)(如配置管理、服務(wù)發(fā)現(xiàn)、斷路器、智能路由、微代理、控制總線、一次性 Token、全局鎖、決策競選、分布式會(huì)話和集群狀態(tài))操作的開發(fā)工具。使用 Spring Cloud 開發(fā)者可以快速實(shí)現(xiàn)上述這些模式。
主要有eureka做服務(wù)發(fā)現(xiàn)、config做分布式配置、zuul做api-gateway、feign做客戶端負(fù)載均衡、hystrix做斷路器、turbine做聚合的monitor、graphite做指標(biāo)監(jiān)控。
http://blog.csdn.net/liaokailin/article/category/6212338
MICROSERVICE WITH SPRING-CLOUD.
https://github.com/kennyk65/Microservices-With-Spring-Student-Files
!!!spring-cloud-study
http://git.oschina.net/itmuch/spring-cloud-study
一個(gè)ring buffer實(shí)現(xiàn)多線程通信。由于他們之間通信不需要鎖所以性能有很大的提高。
Disruptor更多的應(yīng)用在高速事務(wù)中,利用JVM的偽內(nèi)存,這也可能是它為LMAX而生的,和akka的應(yīng)用場景不一樣。
一般編寫并發(fā)應(yīng)用程序馬上想到多線程或者多進(jìn)程。但多線程需要處理資源競爭,共享訪問等問題,搞不好容易出現(xiàn)死鎖,當(dāng)程序規(guī)模比較大時(shí),排查難度很大。 Actor模型提供了另一種編寫并發(fā)應(yīng)用程序的思路。 有點(diǎn)類似Node.JS的基于事件異步處理. (其實(shí)我覺得基于消息異步和基于事件異步是一回事)
什么是基于消息異步呢?很簡單,比如要開展一個(gè)項(xiàng)目,需要多人協(xié)作。作為項(xiàng)目經(jīng)理的你,只需要像手下發(fā)出命令,個(gè)人各干各的,互不干擾。做完了就回送一個(gè)消息給項(xiàng)目經(jīng)理,項(xiàng)目經(jīng)理再分派新的任務(wù). (可能比喻得不恰當(dāng),但Actor的基本思路就是這樣,你不需要考慮資源共享和線程并發(fā)什么的, Actor庫屏蔽了這些底層的實(shí)現(xiàn)細(xì)節(jié) . 每個(gè)Actor就相當(dāng)于一個(gè)人或者叫一個(gè)處理者,他們的職責(zé)很單一,就是響應(yīng)對方發(fā)來的消息,做出響應(yīng),并回送一個(gè)響應(yīng)消息。 每個(gè)Actor負(fù)責(zé)做自己的份內(nèi)事,最后有一個(gè)調(diào)度角色的Actor將所有Actor管理起來,形成一個(gè)整體)
Akka 是針對Scala和Java的Actor庫,JActor是一個(gè)用純Java編寫的Actor庫。
https://github.com/LMAX-Exchange/disruptorhttp://www.oschina.net/p/disruptor
1 JPA概述
JPA(Java Persistence API,Java持久化API),定義了對象-關(guān)系映射(ORM)以及實(shí)體對象持久化的標(biāo)準(zhǔn)接口。
JPA是JSR-220(EJB3.0)規(guī)范的一部分,在JSR-220中規(guī)定實(shí)體對象(EntityBean)由JPA進(jìn)行支持。
所以JPA不局限于EJB3.0,而是作為POJO持久化的標(biāo)準(zhǔn)規(guī)范,可以脫離容器獨(dú)立運(yùn)行,開發(fā)和測試更加方便。
JPA在應(yīng)用中的位置如下圖所示:

JPA維護(hù)一個(gè)Persistence Context(持久化上下文),在持久化上下文中維護(hù)實(shí)體的生命周期。主要包含三個(gè)方面的內(nèi)容:
- ORM元數(shù)據(jù)。JPA支持annotion或xml兩種形式描述對象-關(guān)系映射。
- 實(shí)體操作API。實(shí)現(xiàn)對實(shí)體對象的CRUD操作。
- 查詢語言。約定了面向?qū)ο蟮牟樵冋Z言JPQL(Java Persistence Query Language)。
JPA的主要API都定義在javax.persistence包中。如果你熟悉Hibernate,可以很容易做出對應(yīng):
org.hibernate | javax.persistence | 說明 |
---|
cfg.Configuration | Persistence | 讀取配置信息 |
SessionFactory | EntityManagerFactory | 用于創(chuàng)建會(huì)話/實(shí)體管理器的工廠類 |
Session | EntityManager | 提供實(shí)體操作API,管理事務(wù),創(chuàng)建查詢 |
Transaction | EntityTransaction | 管理事務(wù) |
Query | Query | 執(zhí)行查詢 |

2 實(shí)體生命周期
實(shí)體生命周期是JPA中非常重要的概念,描述了實(shí)體對象從創(chuàng)建到受控、從刪除到游離的狀態(tài)變換。對實(shí)體的操作主要就是改變實(shí)體的狀態(tài)。
JPA中實(shí)體的生命周期如下圖:

- New,新創(chuàng)建的實(shí)體對象,沒有主鍵(identity)值
- Managed,對象處于Persistence Context(持久化上下文)中,被EntityManager管理
- Detached,對象已經(jīng)游離到Persistence Context之外,進(jìn)入Application Domain
- Removed, 實(shí)體對象被刪除
EntityManager提供一系列的方法管理實(shí)體對象的生命周期,包括:
- persist, 將新創(chuàng)建的或已刪除的實(shí)體轉(zhuǎn)變?yōu)镸anaged狀態(tài),數(shù)據(jù)存入數(shù)據(jù)庫。
- remove,刪除受控實(shí)體
- merge,將游離實(shí)體轉(zhuǎn)變?yōu)镸anaged狀態(tài),數(shù)據(jù)存入數(shù)據(jù)庫。
如果使用了事務(wù)管理,則事務(wù)的commit/rollback也會(huì)改變實(shí)體的狀態(tài)。
3 實(shí)體關(guān)系映射(ORM)
3.1 基本映射
對象端 | 數(shù)據(jù)庫端 | annotion | 可選annotion |
---|
Class | Table | @Entity | @Table(name="tablename") |
property | column | – | @Column(name = "columnname") |
property | primary key | @Id | @GeneratedValue 詳見ID生成策略 |
property | NONE | @Transient | |
3.2 ID生成策略
ID對應(yīng)數(shù)據(jù)庫表的主鍵,是保證唯一性的重要屬性。JPA提供了以下幾種ID生成策略
- GeneratorType.AUTO ,由JPA自動(dòng)生成
- GenerationType.IDENTITY,使用數(shù)據(jù)庫的自增長字段,需要數(shù)據(jù)庫的支持(如SQL Server、MySQL、DB2、Derby等)
- GenerationType.SEQUENCE,使用數(shù)據(jù)庫的序列號,需要數(shù)據(jù)庫的支持(如Oracle)
- GenerationType.TABLE,使用指定的數(shù)據(jù)庫表記錄ID的增長 需要定義一個(gè)TableGenerator,在@GeneratedValue中引用。例如:
@TableGenerator( name="myGenerator", table="GENERATORTABLE", pkColumnName = "ENTITYNAME", pkColumnValue="MyEntity", valueColumnName = "PKVALUE", allocationSize=1 )
@GeneratedValue(strategy = GenerationType.TABLE,generator="myGenerator")
3.3 關(guān)聯(lián)關(guān)系
JPA定義了one-to-one、one-to-many、many-to-one、many-to-many 4種關(guān)系。
對于數(shù)據(jù)庫來說,通常在一個(gè)表中記錄對另一個(gè)表的外鍵關(guān)聯(lián);對應(yīng)到實(shí)體對象,持有關(guān)聯(lián)數(shù)據(jù)的一方稱為owning-side,另一方稱為inverse-side。
為了編程的方便,我們經(jīng)常會(huì)希望在inverse-side也能引用到owning-side的對象,此時(shí)就構(gòu)建了雙向關(guān)聯(lián)關(guān)系。 在雙向關(guān)聯(lián)中,需要在inverse-side定義mappedBy屬性,以指明在owning-side是哪一個(gè)屬性持有的關(guān)聯(lián)數(shù)據(jù)。
對關(guān)聯(lián)關(guān)系映射的要點(diǎn)如下:
關(guān)系類型 | Owning-Side | Inverse-Side |
---|
one-to-one | @OneToOne | @OneToOne(mappedBy="othersideName") |
one-to-many / many-to-one | @ManyToOne | @OneToMany(mappedBy="xxx") |
many-to-many | @ManyToMany | @ManyToMany(mappedBy ="xxx") |
其中 many-to-many關(guān)系的owning-side可以使用@JoinTable聲明自定義關(guān)聯(lián)表,比如Book和Author之間的關(guān)聯(lián)表:
@JoinTable(name = "BOOKAUTHOR", joinColumns = { @JoinColumn(name = "BOOKID", referencedColumnName = "id") }, inverseJoinColumns = { @JoinColumn(name = "AUTHORID", referencedColumnName = "id") })
關(guān)聯(lián)關(guān)系還可以定制延遲加載和級聯(lián)操作的行為(owning-side和inverse-side可以分別設(shè)置):
通過設(shè)置fetch=FetchType.LAZY 或 fetch=FetchType.EAGER來決定關(guān)聯(lián)對象是延遲加載或立即加載。
通過設(shè)置cascade={options}可以設(shè)置級聯(lián)操作的行為,其中options可以是以下組合:
- CascadeType.MERGE 級聯(lián)更新
- CascadeType.PERSIST 級聯(lián)保存
- CascadeType.REFRESH 級聯(lián)刷新
- CascadeType.REMOVE 級聯(lián)刪除
- CascadeType.ALL 級聯(lián)上述4種操作
3.4 繼承關(guān)系
JPA通過在父類增加@Inheritance(strategy=InheritanceType.xxx)來聲明繼承關(guān)系。A支持3種繼承策略:
- 單表繼承(InheritanceType.SINGLETABLE),所有繼承樹上的類共用一張表,在父類指定(@DiscriminatorColumn)聲明并在每個(gè)類指定@DiscriminatorValue來區(qū)分類型。
- 類表繼承(InheritanceType.JOINED),父子類共同的部分公用一張表,其余部分保存到各自的表,通過join進(jìn)行關(guān)聯(lián)。
- 具體表繼承(InheritanceType.TABLEPERCLASS),每個(gè)具體類映射到自己的表。
其中1和2能夠支持多態(tài),但是1需要允許字段為NULL,2需要多個(gè)JOIN關(guān)系;3最適合關(guān)系數(shù)據(jù)庫,對多態(tài)支持不好。具體應(yīng)用時(shí)根據(jù)需要取舍。
4 事件及監(jiān)聽

通過在實(shí)體的方法上標(biāo)注@PrePersist,@PostPersist等聲明即可在事件發(fā)生時(shí)觸發(fā)這些方法。
5 Query Language 查詢語言
JPA提供兩種查詢方式,一種是根據(jù)主鍵查詢,使用EntityManager的find方法:
T find(Class entityClass, Object primaryKey)
另一種就是使用JPQL查詢語言。JPQL是完全面向?qū)ο蟮模邆淅^承、多態(tài)和關(guān)聯(lián)等特性,和hibernate HQL很相似。
使用EntityManager的createQuery方法:
Query createQuery(String qlString)
5.1 使用參數(shù)
可以在JPQL語句中使用參數(shù)。JPQL支持命名參數(shù)和位置參數(shù)兩種參數(shù),但是在一條JPQL語句中所有的參數(shù)只能使用同一種類型。
舉例如下:
Query query = em.createQuery("select p from Person p where p.personid=:Id"); query.setParameter("Id",new Integer(1));
Query query = em.createQuery("select p from Person p where p.personid=?1"); query.setParameter(1,new Integer(1));
5.2 命名查詢
如果某個(gè)JPQL語句需要在多個(gè)地方使用,還可以使用@NamedQuery 或者 @NamedQueries在實(shí)體對象上預(yù)定義命名查詢。
在需要調(diào)用的地方只要引用該查詢的名字即可。
例如:
@NamedQuery(name="getPerson", query= "FROM Person WHERE personid=?1")
@NamedQueries({ @NamedQuery(name="getPerson1", query= "FROM Person WHERE personid=?1"), @NamedQuery(name="getPersonList", query= "FROM Person WHERE age>?1") })
Query query = em.createNamedQuery("getPerson");
5.3 排序
JPQL也支持排序,類似于SQL中的語法。例如: Query query = em.createQuery("select p from Person p order by p.age, p.birthday desc");
5.4 聚合查詢
JPQL支持AVG、SUM、COUNT、MAX、MIN五個(gè)聚合函數(shù)。例如:
Query query = em.createQuery("select max(p.age) from Person p"); Object result = query.getSingleResult(); String maxAge = result.toString();
5.5 更新和刪除
JPQL不僅用于查詢,還可以用于批量更新和刪除。
如:
Query query = em.createQuery("update Order as o set o.amount=o.amount+10"); //update 的記錄數(shù) int result = query.executeUpdate();
Query query = em.createQuery("delete from OrderItem item where item.order in(from Order as o where o.amount<100)"); query.executeUpdate();
query = em.createQuery("delete from Order as o where o.amount<100"); query.executeUpdate();//delete的記錄數(shù)
6 事務(wù)管理
JPA支持本地事務(wù)管理(RESOURCELOCAL)和容器事務(wù)管理(JTA),容器事務(wù)管理只能用在EJB/Web容器環(huán)境中。
事務(wù)管理的類型可以在persistence.xml文件中的“transaction-type”元素配置。
JPA中通過EntityManager的getTransaction()方法獲取事務(wù)的實(shí)例(EntityTransaction),之后可以調(diào)用事務(wù)的begin()、commit()、rollback()方法。
Date: 2012-12-30 16:46:29 CST
Author: Holbrook
Org version 7.8.11 with Emacs version 24
git有諸多好處,網(wǎng)上都說的很清楚了,在這里我不再贅述。對于我來說,私下里想做一些項(xiàng)目,而又不能很好的保存自己的代碼和進(jìn)行版本控制,這時(shí)候,就用到了git。下面,就以我個(gè)人為例講講git從0開始如何安裝使用。
Step1 準(zhǔn)備工作
msysgit,下載地址為http://msysgit.github.io/。
Eclipse IDE for Java EE Developers(必須是這個(gè),自帶Egit,或者自行安裝Egit插件),在Eclipse官網(wǎng)下載,地址http://www.eclipse.org/downloads/。
github賬號,github官網(wǎng)注冊一個(gè),地址https://github.com/。
廖雪峰的git教程,地址為http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000,講得很好,我大概花了3個(gè)晚上的時(shí)間看,如果僅僅是為了安裝上,可以先暫時(shí)略過,后面再看。
Step2 msysgit安裝
一路next就行,注意可能會(huì)遇到360的攔截(該死,點(diǎn)擊允許本程序所有操作或者安裝前就退出360即可)。
Step3 git用戶名和郵箱配置
單擊開始菜單,打開Git Bush,

輸入以下命令
git config --global user.name "Your Name"
git config --global user.email email@example.com
用戶名和郵箱替換為自己的,為本臺機(jī)器所有倉庫指定用戶名和email地址。
Step4 創(chuàng)建SSH Key
因?yàn)楸镜豨it倉庫和遠(yuǎn)程的github倉庫之間是通過ssh加密的,所以,還需要?jiǎng)?chuàng)建一個(gè)SSH Key。
輸入以下命令
ssh-keygen -t rsa -C youremail@example.com
同樣將郵箱替換為自己的。在路徑C盤->用戶->用戶名,找到.ssh文件夾,打開就可以看到兩個(gè)文件id_rsa和id_rsa.pub,
打開id_rsa.pub,將其中的內(nèi)容復(fù)制下來(這就相當(dāng)于一把鑰匙,持有鑰匙的人可以訪問你的內(nèi)容,下一個(gè)小結(jié)講解這把鑰匙的用途),下面是我的

Step5 與github上的倉庫相關(guān)聯(lián)
注冊一個(gè)github賬號
注冊完成之后,點(diǎn)擊右上角的settings(就是那個(gè)齒輪,設(shè)置的圖標(biāo))

進(jìn)入設(shè)置頁面

選SSH Keys,點(diǎn)擊add SSH key,就可以添加了,title隨便填寫,將從id_rsa.pub中復(fù)制的內(nèi)容粘貼到這里。從此,gitgub倉庫就能夠識別你本地的倉庫了。也就是說,你離將本地代碼推送到github上,或者將github上的代碼克隆到本地,就只差一步了。(可參考廖雪峰前輩的教程先進(jìn)行在非Eclipse下的操作,更有感覺)
Step6 Egit的使用
首先,登入你的github賬號,點(diǎn)擊加號,選擇New repositrory,創(chuàng)建一個(gè)新的倉庫,如圖所示。

名字叫做test2,其他都默認(rèn)就好。
點(diǎn)擊綠色按鈕創(chuàng)建,就創(chuàng)建好了一個(gè)github倉庫。

將地址復(fù)制下來,保存好備用。
打開Eclipse,像平常一樣,新建一個(gè)web工程,或者其他你常用的工程。我這里工程叫做scott
![{4$7`FVS]283EW(~80FR(JT {4$7`FVS]283EW(~80FR(JT](http://images.cnitblog.com/blog/465427/201409/252120388895169.jpg)
右擊項(xiàng)目,選擇Team->Share Project,彈出如下窗口。

選擇git,next,在彈出的界面上,①先勾選Use or create……,②createrepository,③勾選工程,④finish。

這時(shí)候,你就創(chuàng)建好了一個(gè)git工程,右擊工程,選擇Team,你可以像svn一樣進(jìn)行commit,synchronize等操作,但是,remote操作中,push是灰色的,表示還不能將代碼推送到github倉庫上去。

這時(shí),打開Git Repository視圖(具體怎么打開百度去,這都是基本常識了)

右鍵選擇Create Remote,點(diǎn)OK

點(diǎn)擊Change,彈出如下界面

URI輸入之前在github上拷貝的地址,下面的內(nèi)容會(huì)自動(dòng)填上。你只需要再填上github上的用戶名和密碼即可。finish,save。
接下來的幾步就簡單了,在項(xiàng)目里面隨便寫點(diǎn)代碼,然后先將新增的代碼提交到本地,例如,將cat類,先add to index,然后commit。這時(shí)候,右鍵工程,Team->remote中就有了push選項(xiàng),意味著你可以將本地代碼保存在github中了。祝賀你!

點(diǎn)擊Push,點(diǎn)擊add All Branches Spec,將本地版本庫添加,然后Finish,后面一路Next,再次查看github,可以看到代碼已經(jīng)成功推送。

最后,看看我們在github上的代碼吧!

作者: 張萬帆
歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處。
一、Eclipse上安裝GIT插件EGit
Eclipse的版本eclipse-java-helios-SR2-win32.zip(在Eclipse3.3版本找不到對應(yīng)的 EGit插件,無法安裝)


EGit插件地址:http://download.eclipse.org/egit/updates
OK,隨后連續(xù)下一步默認(rèn)安裝就可以,安裝后進(jìn)行重啟Eclipse
二、在Eclipse中配置EGit
準(zhǔn)備工作:需要在https://github.com 上注冊賬號
Preferences > Team > Git > Configuration

這里的user.name 是你在https://github.com上注冊用戶名

user.email是你在github上綁定的郵箱。在這里配置user.name即可
三、新建項(xiàng)目,并將代碼提交到本地的GIT倉庫中
1、新建項(xiàng)目 git_demo,并新建HelloWorld.java類

2、將git_demo項(xiàng)目提交到本地倉庫,如下圖



到此步,就成功創(chuàng)建GIT倉庫。但文件夾處于untracked狀態(tài)(文件夾中的符號”?”表示),下面我們需要提交代碼到本地倉庫,如下圖



OK,這樣代碼提交到了本地倉庫
四:將本地代碼提交到遠(yuǎn)程的GIT倉庫中
準(zhǔn)備工作:在https://github.com上創(chuàng)建倉庫


點(diǎn)擊“Create repository” ,ok,這樣在github上的倉庫就創(chuàng)建好了。
注意創(chuàng)建好遠(yuǎn)程倉庫后,點(diǎn)擊進(jìn)去,此時(shí)可以看到一個(gè)HTTP地址,如紅線框,這個(gè)是你http協(xié)議的遠(yuǎn)程倉庫地址

準(zhǔn)備工作做好了,那開始將代碼提交到遠(yuǎn)程倉庫吧






OK,這樣提交遠(yuǎn)程GIT就完成了,可以在https://github.com核對一下代碼是否已經(jīng)提交

注意的問題
如果是首次提交會(huì)第一步:先在本地建立一個(gè)一樣的倉庫,稱本地倉庫。
第二步:在本地進(jìn)行commit操作將把更新提交到本地倉庫;
第三步: 將服務(wù)器端的更新pull到本地倉庫進(jìn)行合并,最后將合并好的本地倉庫push到服務(wù)器端,這樣就進(jìn)行了一次遠(yuǎn)程提交。
如果非首次提交同樣的道理
第一步:將修改的代碼commit操作更新到本地倉庫;
第二步:第三步: 將服務(wù)器端的更新pull到本地倉庫進(jìn)行合并,最后將合并好的本地倉庫push到服務(wù)器端
上個(gè)月,我貼了《圖形化簡歷》。
幾天后,就收到了秋葉老師的來信,希望與我探討一些設(shè)計(jì)問題。他寫過一本暢銷書《說服力-讓你的PPT會(huì)說話》,眼下正在寫續(xù)集。
我看了新書的樣章,覺得很不錯(cuò),有些內(nèi)容很值得分享。
====================================
首先,我們先看一個(gè)例子。良好的設(shè)計(jì)如何使得一個(gè)平庸的文檔脫胎換骨。下面是一張大學(xué)生的求職簡歷,再普通不過了,想要引起招聘經(jīng)理的注意,恐怕很難。

秋葉老師對它進(jìn)行了簡單的排版,還是一張表格,還是黑白配色,沒有使用任何圖形元素,效果卻完全不一樣了。

真是令人眼前一亮,不由自主地想多看幾眼。這就是優(yōu)秀設(shè)計(jì)的作用:它讓你脫穎而出。
====================================
秋葉老師把他的排版心得,總結(jié)為六個(gè)原則:對齊,聚攏,重復(fù),對比,強(qiáng)調(diào),留白。我是這樣理解的:
一、對齊原則
相關(guān)內(nèi)容必須對齊,次級標(biāo)題必須縮進(jìn),方便讀者視線快速移動(dòng),一眼看到最重要的信息。
二、聚攏原則
將內(nèi)容分成幾個(gè)區(qū)域,相關(guān)內(nèi)容都聚在一個(gè)區(qū)域中。段間距應(yīng)該大于段內(nèi)的行距。
三、留白原則
千萬不要把頁面排得密密麻麻,要留出一定的空白,這本身就是對頁面的分隔。這樣既減少了頁面的壓迫感,又可以引導(dǎo)讀者視線,突出重點(diǎn)內(nèi)容。
四、降噪原則
顏色過多、字?jǐn)?shù)過多、圖形過繁,都是分散讀者注意力的"噪音"。
五、重復(fù)原則
多頁面排版時(shí),注意各個(gè)頁面設(shè)計(jì)上的一致性和連貫性。另外,在內(nèi)容上,重要信息值得重復(fù)出現(xiàn)。
六、對比原則
加大不同元素的視覺差異。這樣既增加了頁面的活潑,又方便讀者集中注意力閱讀某一個(gè)子區(qū)域。
====================================
下面用一個(gè)PPT的例子,演示排版六原則。

上面這張ppt有兩個(gè)毛病。一是字?jǐn)?shù)太多,抓不住重點(diǎn);二是右邊沒有對齊,使得讀者的視線只能一行行地從行首到行尾移動(dòng),不能直上直下。

現(xiàn)在進(jìn)行修改。
第一步,根據(jù)"聚攏原則",將六點(diǎn)分成六個(gè)區(qū)域。
第二步,根據(jù)"降噪原則",將每一點(diǎn)分成"小標(biāo)題"和"說明文字"兩部分。
第三步,根據(jù)"對齊原則",將每一個(gè)部分、每一種元素對齊。
第四步,根據(jù)"對比原則",加大"小標(biāo)題"和"說明文字"在字體和顏色上的差異。
第五步,根據(jù)"留白原則",留出一定的空白。

頁面的可讀性大大增加。
(完)
1)什么是MyThrift?
基于以下組件打造的一款輕量級RPC服務(wù)框架:thrift(facebook出品)、commons-pool(socket連接池)、自研服務(wù)治理框架(zookeeper).
2)為什么要寫MyThrift?
2.1)提出問題:
各種存儲越來越多(redis,mysql,hdfs,hbase,mq),
讓web開發(fā)人員自己訪問存儲,并保證性能,是一件高要求的事情。
造成的結(jié)果就是軟件開發(fā)進(jìn)度緩慢,性能低下,各種bug.
2.2)分析問題:
RPC框架:考慮到本人看過thrift的源碼,尤其是針對網(wǎng)絡(luò)模塊非常熟悉,并在實(shí)際生產(chǎn)環(huán)境中使用過,thrift性能不錯(cuò)。
TCP/IP:有過2年的TCP/IP報(bào)文分析經(jīng)驗(yàn),從鏈路層到應(yīng)用層都很熟悉。
ZooKeeper:在MySQL-Binlog項(xiàng)目中攢出了一些使用經(jīng)驗(yàn),同時(shí)積極吸收Motan,JACK,HArpc等兄弟軟件的優(yōu)秀理念部分。
連接池:使用commons-pool連接池組件。
2.3)解決問題:
糅合thrift,zookeeper,commons-pool打造一款輕量級、性能高、上手容易的rpc調(diào)用框架,
使得架構(gòu)師和后臺開發(fā)人員可以將各種復(fù)雜存儲的IO訪問對外暴露為服務(wù)(其實(shí)就是跨機(jī)器的普通函數(shù)調(diào)用)
這樣web開發(fā)人員可以專注于業(yè)務(wù)邏輯,加速產(chǎn)品迭代,對企業(yè)帶來的好處不用多說!
本次版本內(nèi)容:
1)server端進(jìn)行網(wǎng)絡(luò)模型參數(shù)調(diào)優(yōu)
2)client端有連接池
3)支持server注冊多個(gè)thrift的處理器Processor
可用于集中式負(fù)載的服務(wù)化組件,達(dá)到生產(chǎn)環(huán)境級別,經(jīng)歷過生產(chǎn)環(huán)境的考驗(yàn),可放心使用。
http://git.oschina.net/qiangzigege/MyThrift
內(nèi)附非常詳細(xì)+多圖預(yù)警的《MyThrift在線使用文檔.md》,0基礎(chǔ)輕松上手!
在移動(dòng)互聯(lián)網(wǎng)時(shí)代,我們面對的是更多的客戶端,更低的請求延遲,這當(dāng)然需要對數(shù)據(jù)做大量的 Cache 以提高讀寫速度。
術(shù)語
- 節(jié)點(diǎn):指集群里的一臺服務(wù)器。
現(xiàn)有 Cache 系統(tǒng)的特點(diǎn)
目前業(yè)界使用得最多的 Cache 系統(tǒng)主要是 memcached 和 redis。 這兩個(gè) Cache 系統(tǒng)都有都有很大的用戶群,可以說是比較成熟的解決方案,也是很多系統(tǒng)當(dāng)然的選擇。 不過,在使用 memcached 和 redis 過程中,還是碰到了不少的問題和局限:
- Cluster 支持不夠。在擴(kuò)容、負(fù)載均衡、高可用等方面存在明顯不足。
- 持久化支持不好,出現(xiàn)問題后恢復(fù)的代價(jià)大。memcached 完全不支持持久化,redis 的持久化會(huì)造成系統(tǒng)間歇性的負(fù)載很高。
我期待的理想 Cache 系統(tǒng)
良好的 cluster 支持
- Key 可以動(dòng)態(tài)分散(Auto Sharding)在不同的服務(wù)器上,可以通過動(dòng)態(tài)添加服務(wù)器節(jié)點(diǎn)增加系統(tǒng)容量。
- 沒有單點(diǎn)失效,任何一個(gè)單點(diǎn)都不會(huì)造成數(shù)據(jù)不可訪問。
- 讀寫負(fù)載可以均勻分布在系統(tǒng)的不同節(jié)點(diǎn)上。
支持異步持久化支持
- 方便快速恢復(fù),甚至可以直接用作 key/value 數(shù)據(jù)庫。 經(jīng)常在跟業(yè)界朋友交流時(shí),會(huì)提到用 key 分段的方法來做容量擴(kuò)展以及負(fù)載均衡。但是用靜態(tài)的 key 分段會(huì)有不少問題:
- Cache 系統(tǒng)本身及使用 cache 的客戶端都需要預(yù)設(shè)一個(gè)分段邏輯,這個(gè)邏輯后期如果需要調(diào)整將會(huì)非常困難。不能解決單點(diǎn)失效的問題,還需要額外的手段。運(yùn)維需要更多的人為參與,避免 key 超出現(xiàn)有分區(qū),一旦出現(xiàn) key 找不到對應(yīng)服務(wù)器,訪問直接失敗。
最接近需求的系統(tǒng):Couchbase
基于這些想法,我花了幾天時(shí)間在 google, stack overflow, quora 上看了很多大家關(guān)于 cache cluster 的討論,找到一個(gè)比較新系統(tǒng) Couchbase。
memcached VS couchbase
Couchbase 的集群設(shè)計(jì)對等網(wǎng)
Couchbase 群集所有點(diǎn)都是對等的,只是在創(chuàng)建群或者加入集群時(shí)需要指定一個(gè)主節(jié)點(diǎn),一旦結(jié)點(diǎn)成功加入集群,所有的結(jié)點(diǎn)對等。

圖片來源:couchbase.com
對等網(wǎng)的優(yōu)點(diǎn)是,集群中的任何節(jié)點(diǎn)失效,集群對外提供服務(wù)完全不會(huì)中斷,只是集群的容量受影響。 Smart Client
由于 couchbase 是對等網(wǎng)集群,所有的節(jié)點(diǎn)都可以同時(shí)對客戶端提供服務(wù),這就需要有方法把集群的節(jié)點(diǎn)信息暴露給客戶端,couchbase 提供了一套機(jī)制,客戶端可以獲取所有節(jié)點(diǎn)的狀態(tài)以及節(jié)點(diǎn)的變動(dòng),由客戶端根據(jù)集群的當(dāng)前狀態(tài)計(jì)算 key 所在的位置。 vBucket
vBucket 概念的引入,是 couchbase 實(shí)現(xiàn) auto sharding,在線動(dòng)態(tài)增減節(jié)點(diǎn)的重要基礎(chǔ)。
簡單的解釋 vBucket 可以從靜態(tài)分片開始說起,靜態(tài)分片的做法一般是用 key 算出一個(gè) hash,得到對應(yīng)的服務(wù)器,這個(gè)算法很簡單,也容易理解。如以下代碼所示:
servers = ['server1:11211', 'server2:11211', 'server3:11211'] server_for_key(key) = servers[hash(key) % servers.length]
但也有幾個(gè)問題:
- 如果一臺服務(wù)器失效,會(huì)造成該分片的所有 key 失效。
- 如果服務(wù)器容量不同,管理非常麻煩。
- 前面提到過,運(yùn)維、配置非常不方便。
為了把 key 跟服務(wù)器解耦合,couchbase 引入了 vBucket。可以說 vBucket 代表一個(gè) cache 子集,主要特點(diǎn):
- key hash 對應(yīng)一個(gè) vBucket,不再直接對應(yīng)服務(wù)器。
- 集群維護(hù)一個(gè)全局的 vBucket 與服務(wù)器對應(yīng)表。
- 前面提到的 smart client 重要的功能就是同步 vBucket 表。
如以下代碼所示:
servers = ['server1:11211', 'server2:11211', 'server3:11211'] vbuckets = [0, 0, 1, 1, 2, 2] server_for_key(key) = servers[vbuckets[hash(key) % vbuckets.length]]

圖片來源:http://dustin.sallings.org/2010/06/29/memcached-vbuckets.html
由于 vBucket 把 key 跟服務(wù)器的靜態(tài)對應(yīng)關(guān)系解耦合,基于 vBucket 可以實(shí)現(xiàn)一些非常強(qiáng)大有趣的功能,例如:
- Replica,以 vBucket 為單位的主從備份。如果某個(gè)節(jié)點(diǎn)失效,只需要更新 vBucket 映射表,馬上啟用備份數(shù)據(jù)。
- 動(dòng)態(tài)擴(kuò)容。新增加一個(gè)節(jié)點(diǎn)后,可以把部分 vBucket 轉(zhuǎn)移到新節(jié)點(diǎn)上,并更新 vBucket 映射表。
vBucket 非常重要,以后可以單獨(dú)寫一篇文章分享。
總結(jié)
- Couchbase 的對等網(wǎng)設(shè)計(jì),smart client 直接獲取整的集群的信息,在客戶端實(shí)現(xiàn)負(fù)載均衡,整個(gè)集群沒有單點(diǎn)失效,并且完全支持平行擴(kuò)展。
- vBucket 的引入,完全實(shí)現(xiàn)了 auto sharding,可以方便靈活的把數(shù)據(jù)的子集在不同節(jié)點(diǎn)上移動(dòng),以實(shí)現(xiàn)集群動(dòng)態(tài)管理。
- Couchbase 有一個(gè)非常專業(yè)的 web 管理界面,并且支持通過 RESTful API 管理,這也是 memcached, redis 不能企及的。
- 如果只是做 key/value 的 cache,Couchbase 可以完全取代 memcached。
- Couchbase 已經(jīng)被我們在生產(chǎn)環(huán)境中大量采用。