1. 請問,有誰知道怎麼全局緩存jsapi ticket的嗎請大師指導
public class TokenSingleton
{
//緩存accessToken 的Map ,map中包含 accessToken jsapiticket 和 緩存的時間戳
//當然也可以分開成兩個屬性咯
private Dictionary<string, string> map = new Dictionary<string, string>();
private TokenSingleton()
{
}
private static TokenSingleton single = null;
// 靜態工廠方法
public static TokenSingleton getInstance()
{
if (single == null)
{
single = new TokenSingleton();
}
return single;
}
public Dictionary<string, string> getMap()
{
string time = map["time"];
string accessToken = map["access_token"];
string jsapiticket = map["jsapi_ticket"];
long nowDate = Framework.HttpHelper.HttpRequest.GetCurrentUinxTime();
if (accessToken != null && time != null && nowDate - long.Parse(time) < 3000 * 1000)
{
//alert("accessToken存在,且沒有超時 , 返回單例");
}
else {
//alert("accessToken 超時 , 或者不存在 , 重新獲取");
//獲取access_token
string access_token = getAccessToken(appid, secret );
if (!string.IsNullOrEmpty(access_token))
{
map.Add("time", nowDate + "");
map.Add("access_token", access_token);
//獲取jsapi_ticket
string jsapi_token = getJsapiTicket(access_token);
if (!string.IsNullOrEmpty(jsapi_token))
{
map.Add("jsapi_ticket", jsapi_token);
}
}
}
return map;
}
public void setMap(Dictionary<string, string> map)
{
this.map = map;
}
public static TokenSingleton getSingle()
{
return single;
}
public static void setSingle(TokenSingleton single)
{
TokenSingleton.single = single;
}
public string getAccessToken(string appid, string secret )
{
// 這個url鏈接地址和參數皆不能變
string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
string result = doHttpGet(url);
dynamic resultStr = JsonConvert.DeserializeObject(result, new { access_token = "", expires_in = "", errcode = "", errmsg = "" }.GetType());
//請求成功
if (resultStr != null && !string.IsNullOrWhiteSpace(resultStr.access_token))
{
return resultStr.access_token;
}
else
{
return "";
}
}
public string getJsapiTicket(string accessToken)
{
//獲取jsapi_ticket
// 這個url鏈接地址和參數皆不能變
string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi";
string result = doHttpGet(url);
dynamic resultStr = JsonConvert.DeserializeObject(result, new { errcode = "", errmsg = "", ticket = "", expires_in = "" }.GetType());
//請求成功
if (resultStr.errcode == "0" && resultStr.errmsg == "ok")
{
return resultStr.ticket;
}
else
{
return "";
}
}
public static string doHttpGet(string url)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.ContentType = "application/json";
request.Timeout = 1000 * 60 * 8;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
StreamReader reader = new StreamReader(response.GetResponseStream() ?? throw new InvalidOperationException(), Encoding.UTF8);
string result = reader.ReadToEnd();
response.Close();
return result;
}
else
{
response.Close();
return response.Headers.ToString();
}
}
public static long GetCurrentUinxTime()
{
DateTime currentDate = DateTime.Now;//當前時間
//轉化為時間戳
DateTime localTime = new DateTime(1970, 1, 1, 8, 0, 0);//TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
return long.Parse((currentDate - localTime).TotalSeconds.ToString().Split('.')[0]);
}
}
2. 如何設計好的RESTful API
安全是恆久的話題,對於基於WSDL和SOAP的Web Service,我們有WS-Security這樣的安全規范來指導實現認證、授權、身份管理等安全需求。那麼,RESTful API有無成熟可用規范或實現框架呢?如何保證RESTful API的安全性呢?
如何對RESTful API進行版本控制,請分享您認為實用的做法?
HTTP1.1規范中給出的動詞對於設計RESTful API夠用嗎?您在實際項目中會擴展自己的動詞嗎?在什麼情況下需要擴展?
今年5月份發布的JAX-RS 2.0規范對於RSTfulAPI的設計最有價值的特性是哪個(些)? 它(們)用於解決什麼問題?
能否為InfoQ的讀者們推薦一款實用的RESTful API開發框架,並說明您的推介理由。
HTTP2.0規范正在制定當中,您對它的期待是什麼?
InfoQ:什麼是好的RESTful API?相信每個人都有自己的評判標准。那麼,您認為一個好的RESTful API應該具有哪些特徵呢?
李錕:一個好的RESTful API,應該具備以下特徵:
這個API應該是對瀏覽器友好的,能夠很好地融入Web,而不是與Web格格不入。
瀏覽器是最常見和最通用的REST客戶端。好的RESTful API應該能夠使用瀏覽器+HTML完成所有的測試(不需要使用編程語言)。這樣的API還可以很方便地使用各種自動化的Web功能測試、性能測試工具來做測試。Web前端應用(基於瀏覽器的RIA應用、移動App等等)也可以很方便地將多個RESTful API的功能組合起來,建造Mashup類的應用。
這個API中所包含的資源和對於資源的操作,應該是直觀和容易理解的,並且符合HTTP協議的要求。
REST開發又被稱作「面向資源的開發」,這說明對於資源的抽象,是設計RESTful API的核心內容。RESTful API建模的過程與面向對象建模類似,是以名詞為核心的。這些名詞就是資源,任何可命名的抽象概念都可以定義為一個資源。而HTTP協議並不是一種傳輸協議,它實際提供了一個操作資源的統一介面。對於資源的任何操作,都應該映射到HTTP的幾個有限的方法(常用的有GET/POST/PUT/DELETE四個方法,還有不常用的PATCH/HEAD/OPTIONS方法)上面。所以RESTful API建模的過程,可以看作是具有統一介面約束的面向對象建模過程。
按照HTTP協議的規定,GET方法是安全且冪等的,POST方法是既不安全也不冪等的(可以用來作為所有寫操作的通配方法),PUT、DELETE方法都是不安全但冪等的。將對資源的操作合理映射到這四個方法上面,既不過度使用某個方法(例如過度使用GET方法或POST方法),也不添加過多的操作以至於HTTP的四個方法不夠用。
如果發現資源上的操作過多,以至於HTTP的方法不夠用,應該考慮設計出更多的資源。設計出更多資源(以及相應的URI)對於RESTful API來說並沒有什麼害處。
這個API應該是松耦合的。
RESTful API的設計包括了三個循序漸進、由低到高的層次:資源抽象、統一介面、超文本驅動。正是這三個層次確保了RESTful API的松耦合性。
當設計面向互聯網的API時,松耦合變成了一種「必須有」的強需求。緊耦合的API非常脆弱,一旦公布出去,伺服器端和客戶端都無法持續進化。尤其是伺服器端,公布出去的介面根本不敢改,改了之後,幾乎所有客戶端應用立即無法正常工作。REST這種架構風格就是緊耦合API的解毒劑,這個話題可以談的很深,這里就不展開了。感興趣的讀者可以參考《REST實戰》。
這個API中所使用的表述格式應該是常見的通用格式
在RESTful API中,對於資源的操作,是通過在伺服器端-客戶端之間傳遞資源的表述來間接完成的。資源的表述可以有很多種格式,並且在響應和請求中的資源表述格式也會有所不同。GET/POST響應中的資源表述格式,常見的有HTML、XML、JSON;POST/PUT請求中的資源表述格式,常見的有標準的HTML表單參數、XML、JSON。
這些常見表述格式,處理起來非常容易,有大量的框架和庫提供支持。所以除非有很合理的要求,通常不需要使用自定義的私有格式。
使用HTTP響應狀態代碼來表達各種出錯情況
HTTP響應狀態代碼,是HTTP協議這個統一介面中用來表達出錯情況的標准機制。響應狀態代碼分成兩部分:status code和reason phase。兩部分都是可定製的,也可以使用標準的status code,只定製reason phase。
如果一個所謂的「RESTful API」對於任何請求都返回200 OK響應,在響應的消息體中返回出錯情況信息,這種做法顯然不符合「確保操作語義的可見性」這個REST架構風格的基本要求。
這個API應該對於HTTP緩存是友好的
充分利用好HTTP緩存是RESTful API可伸縮性的根本。HTTP協議是一個分層的架構,從兩端的user agent到origin server之間,可以插入很多中間組件。而在整個HTTP通信鏈條的很多位置,都可以設置緩存。HTTP協議內建有很好的緩存機制,可以分成過期模型和驗證模型兩套緩存機制。如果API設計者完全沒有考慮過如何利用HTTP緩存,那麼這個API的可伸縮性會有很多問題。
李建業:首先說明一下,對REST這個概念,我一般把它理解為REST風格的架構,但是現在實踐中最為廣泛認知的是HTTP,而它是REST的一個實現,所以RESTful API也可以不太嚴格的指基於HTTP的API——當然,即使是不嚴格的時候,API本身也應該力求遵循REST架構風格。
我認為,一個RESTful API最重要的一點應該是——「盡可能少的先驗信息」,這一條也同時是我判斷一個好的RESTful API的標准。
比如HTTP動詞,在實踐中,大家可能會常常糾結於有效利用 HTTP 動詞,但這卻並不是特別重要的事情——除非你理解這么做的價值。HTTP 動詞最重要的地方在於它是標准闡明了的行為,也就是說,如果我們的「客戶端」遵循約定,那麼就不必要發明新的動詞,也就不必增加「先驗信息」;但是,所謂「先驗信息」,針對的是客戶端——對API來說就是調用者,對於一些企業內部系統,或者一些傳統系統,由於「資源」很穩定,對資源的操作也很穩定,這些系統的「調用客戶端」不是瀏覽器而是另一個系統,此時如果強制對應到HTTP動詞,反而會變成額外的「先驗信息」,這時我就不會太拘泥HTTP動詞,自己制定一套動詞放在參數中也可以接受——只要動詞不變化,這個系統依然是REST風格的。
再比如Response裡面的Content-Type,這個有時會被新手忽略,但這其實很重要,因為一般涉及到系統間協同的API,往往不會使用普通的文本,比較常見的是使用json表達復雜結構,而這與通常的預設理解不同(預設一般會認為是text/plain和text/html),所以如果在API中忘記用Content-Type進行區分的話,後續對多種類型的客戶端接入的支持就會變成陷阱(我們多次遇到過這個問題)。而如果一開始就檢查是否增加先驗知識(預設Content-Type為plain或者允許指定Content-Type),那這一困難就可以避免了。
丁雪豐:首先,應該正確地使用HTTP的統一介面,比如HTTP的動詞,如果不分青紅皂白清一色POST那顯然還有改進的餘地;
其次,資源有合適的粒度,可以從三個方面來評判資源的粒度是否合理——網路的效率、表述的大小以及客戶端使用時的易用程度;
最後,是表述的設計,除了表述的正文內容,還有其中的URI和鏈接,這些都是評判一個RESTful API好壞的標准。
馬鈞:在我看來,一個好的API標准,就是能盡量利用到HTTP協議的特性,將HTTP當成一種轉移協議,而不是傳輸協議。包括但不限於:利用HTTP的各種動詞來明確操作;包含有內容協商,可以根據請求頭提供的參數選擇一個資源最合適的媒體類型、語言、字元集和編碼的表現;使用不同的返回代碼來描述各種狀態。但實際上見到過的很多聲稱RESTful API,包括國內的和國外的,能符合這些條件的並不多。parse.com提供的API是我見到過的較為不錯的RESTful API,可以作為範例參考。
InfoQ:安全是恆久的話題,對於基於WSDL和SOAP的Web Service,我們有WS-Security這樣的安全規范來指導實現認證、授權、身份管理等安全需求。那麼,RESTful API有無成熟可用規范或實現框架呢?如何保證RESTful API的安全性呢?
李錕:保證RESTful API的安全性,主要包括三大方面:
a) 對客戶端做身份認證
b) 對敏感的數據做加密,並且防止篡改
c) 身份認證之後的授權
對客戶端做身份認證,有幾種常見的做法:
在請求中加簽名參數
為每個接入方分配一個密鑰,並且規定一種簽名的計算方法。要求接入方的請求中必須加上簽名參數。這個做法是最簡單的,但是需要確保接入方密鑰的安全保存,另外還要注意防範replay攻擊。其優點是容易理解與實現,缺點是需要承擔安全保存密鑰和定期更新密鑰的負擔,而且不夠靈活,更新密鑰和升級簽名演算法很困難。
使用標準的HTTP身份認證機制
HTTP Basic身份認證安全性較低,必須與HTTPS配合使用。HTTP Digest身份認證可以單獨使用,具備中等程度的安全性。
HTTP Digest身份認證機制還支持插入用戶自定義的加密演算法,這樣可以進一步提高API的安全性。不過插入自定義加密演算法在面向互聯網的API中用的不是很多。
這個做法需要確保接入方「安全域-用戶名-密碼」三元組信息的安全保存,另外還要注意防範replay攻擊。
優點:基於標准,得到了廣泛的支持(大量HTTP伺服器端、客戶端庫)。在伺服器端做HTTP身份認證的職責可以由Web Server(例如Nginx)、App Server(例如Tomcat)、安全框架(例如Spring Security)來承擔,對應用開發者來說是透明的。HTTP身份認證機制(RFC 2617)非常好地體現了「分離關注點」的設計原則,而且保持了操作語義的可見性。
缺點:這類基於簡單用戶名+密碼機制的安全性不可能高於基於非對稱密鑰的機制(例如數字證書)。
使用OAuth協議做身份認證
OAuth協議適用於為外部應用授權訪問本站資源的情況。其中的加密機制與HTTP Digest身份認證相比,安全性更高。需要注意,OAuth身份認證與HTTP Digest身份認證之間並不是相互取代的關系,它們的適用場景是不同的。OAuth協議更適合於為面向最終用戶維度的API提供授權,例如獲取隸屬於用戶的微博信息等等。如果API並不是面向最終用戶維度的,例如像七牛雲存儲這樣的存儲服務,這並非是OAuth協議的典型適用場景。
對敏感的數據做加密,並且防止篡改,常見的做法有:
部署SSL基礎設施(即HTTPS),敏感數據的傳輸全部基於SSL。
僅對部分敏感數據做加密(例如預付費卡的卡號+密碼),並加入某種隨機數作為加密鹽,以防範數據被篡改。
身份認證之後的授權,主要是由應用來控制。通常應該實現某種基於角色+用戶組的授權機制,這方面的框架有不少(例如Spring Security),不過大多數開發團隊還是喜歡自己來實現相關功能。
李建業:我不認為安全是RESTful API需要考慮的問題,事實上我覺得這是兩個正交的問題。當然,如果使用RESTful API來提供認證、授權和身份管理,那也算是雙方有關系,但是這和其它風格的API設計所要考慮的問題似乎沒什麼區別,不值得特別注意。
但是在具體設計層面,這兩者的「正交點」上似乎確實有些問題,因為REST是一個推崇狀態無關原則的架構風格,而認證和授權通常基於第三方解決方案,所以往往會出現違背有狀態約束的問題,這個地方我也沒有特別的想法,當然這個困難和原問題關系不大。
至於WS-族的協議,我不太了解,不太能參與討論。
丁雪豐:對於RESTful API,常見的安全措施都是可以繼續使用的。例如,為了防篡改,可以對全部參數進行簽名;為了防範重放攻擊可以在請求中增加一次性的Token,或者短時間內有效的Token;對內容加密可以實現數據防泄露……;對於DDoS攻擊,各種HTTP流量清洗策略,都可以繼續發揮作用,因為這就是基本的HTTP請求。
在授權和認證方面,OAuth 2.0已經基本成熟了,並且得到了廣泛地應用。如果可以,接入第三方賬戶體系是個不錯的選擇,比如Google和Facebook的,國內的當然也有幾個候選。
馬鈞:個人認為RESTful的安全性分為幾個層次,在安全要求較高的場合,可以通過HTTPs這樣的加密協議來保證網路層的安全,應用層的安全可以通過OAuth實現認證,而對於資源的訪問授權,則只能依靠應用程序來實現了。
InfoQ:如何對RESTful API進行版本控制,請分享您認為實用的做法?
李錕:一個比較簡單實用的做法是直接在URI中插入版本號,這樣做允許多個版本的API並行運行。
另一個做法是在HTTP請求中加入自定義頭信息,標明使用的版本號。不過這個做法其實對瀏覽器不夠友好,簡單地使用瀏覽器+HTML無法測試。
李建業:目前比較好的方式還是在uri設計中添加版本信息,其它方法都不如這個實用。
丁雪豐:個人認為最好的版本化,就是沒有明顯的版本。在對已發布的服務進行變更時,要盡量做到兼容,其中包括URI、鏈接和各種不同的表述的兼容,最關鍵的就是在擴展時不能破壞現有的客戶端。例如,要變更一個參數,可以選擇同時兼容新舊兩種輸入,或者保持老參數不動,提供一個新的參數,在文檔中必須做出說明,不推薦新用戶再繼續使用之前的參數。
如果必須要進行不兼容的變更,那麼可以選擇標記不同的版本號,這時可以選擇在路徑或參數中增加版本信息。也有做法是增加HTTP標頭,只是在調用時會稍有不便,推薦前兩種方法。
馬鈞:RESTfulAPI的版本升級,盡量兼容之前的版本,保證原有的API都能正常工作,可以通過HTTP 301轉跳到新的資源。另外一種實用的做法就是在url中保留版本號,同時提供多個版本供客戶端使用,如 v1.rest.com 或者 rest.com/v1/ 這樣。
InfoQ:HTTP1.1規范中給出的動詞對於設計RESTful API夠用嗎?您在實際項目中會擴展自己的動詞嗎?在什麼情況下需要擴展?
李錕:這個問題取決於設計者如何看待和設計資源。如果資源抽象做的很好,對於某個資源的任何操作,通常都能夠映射到CRUD四個類別中。CRUD四個類別對於操作資源來說,絕大多數情況下是完備的。HTTP的GET/POST/PUT/DELETE四個方法,對於CRUD四個類別的操作來說是足夠的,映射關系是Create-POST/Retrieve-GET/Update-PUT/Delete-DELETE。
我們通常不會選擇創建自己的動詞,這樣做對於客戶端開發者來說,需要更多的學習成本。如果在資源上定義的操作過多,我們會選擇拆分出更多的資源。
李建業:一般是夠用的,有時一些「不夠用」的場景是由於我們沒有設計出合理的資源,比如批量操作。但是,正如之前所說的那樣,對於某些內部的、傳統的(因此模型穩定且已知)系統,API提供者和調用者會有自已的固定動詞表,此時沒必要拘泥。另外,我不建議擴展動詞,一旦擴展了動詞,其實已經破壞了我之前說的*「盡可能少的先驗信息」*,那麼,擴展動詞和重新設計動詞的成本差別不大。基於這個考慮,我建議盡可能保持動詞不變,除非你想重新設計動詞表。
丁雪豐:一般情況下,常用的HTTP動詞是夠用的,並沒有出現一定要自己擴展動詞的情況。其實,最常用的也就是GET、POST、DELETE和PUT,而HEAD、OPTIONS、TRACE則基本用不太到。如果出現一時找不到合適的動詞,安全冪等的操作用GET,其他都可以用POST,在設計資源時稍加考慮即可。
馬鈞:在我的實際項目中,只用到了POST,PUT,DELETE,GET這四個動詞。
InfoQ:今年5月份發布的JAX-RS 2.0規范對於RSTfulAPI的設計最有價值的特性是哪個(些)? 它(們)用於解決什麼問題?
李錕:REST開發框架RESTEasy項目負責人Bill Burke,去年寫了一篇文章介紹JAX-RS 2.0。
我同意Bill在文章中的觀點,在JAX-RS 2.0增加的內容中,最重要的三部分為:
a) Client API——用來規范化JAX-RS客戶端的開發方式。
b) Server-side Asynchronous HTTP——用來實現伺服器端推送功能,而不需要依靠低效的輪詢方式。
c) Filters and Interceptors——用來分離關注點,將鑒權、日誌等邏輯與業務邏輯分離開,更好地實現代碼重用。
這三部分的內容對於開發者來說都很有用。遵循JAX-RS規范做開發,可以確保伺服器端以及客戶端代碼的可移植性。
李建業:我個人關注非同步API這部分,主要是因為流式服務將會越來越多,那將大量需要這類支持。
InfoQ:能否為InfoQ的讀者推薦一款實用的RESTful API開發框架,並說明您的推介理由。
李錕:這個問題我就不詳細回答了。不同的編程語言有不同的REST開發框架,對於REST的支持程度也不同。開發RESTful API的需求范圍很廣,可選擇的開發框架的范圍也很廣。保持多樣性是繁榮生態環境的基礎。像Java就有支持JAX-RS規范的Jersey、RESTEasy、Restlet、Apache CXF,和不支持JAX-RS規范的Spring MVC等等很多框架。這些框架目前都做的不錯。我對框架的選擇沒有傾向性。RESTful API設計的最佳實踐應該是通用的,而不是必須依賴某種特定的開發框架。
李建業:不好意思,這個我不太重視,沒法推薦,不過我可以解釋一下為什麼對RESTful API框架不感冒的原因。
REST作為一個架構風格,對我們的系統開發有很大影響,但是這些影響一般是針對架構(例如狀態無關)或者設計(例如資源識別)上的,所以一旦涉及到具體實現,主要工作就基本結束了,此時開發框架能做的事也就只有簡化編程了(相較而言,有的框架還能起到引導設計的作用),而由於RESTful會抽象動詞,所以實現層面中和API規范相關的工作本來就不多,那麼框架的價值就更小了。
當然,我們也不可能直接基於servlet/rakc/wsgi來開發,不過一般的編程語言都會提供一些簡單的url route/match策略,我們使用這些就足夠了。另外,有些框架能幫我們生成全部的動詞支持,但這也未必是好事,我一般傾向於按需實現——用到了再支持,這就更不需要太關注開發框架對RESTful的支持了。
丁雪豐:由於本人是Spring的擁護者,工作中也一直在使用Spring,所以在選擇框架時會更多地傾向Spring MVC(並不是說別的框架不好,這里有些個人主觀的成份)。如果一定要選擇其他框架,也要選擇能夠方便與Spring集成的框架。如果在項目中已經使用了Spring,那麼沒有什麼理由不選擇Spring MVC,鑒於目前Spring在各種項目中的高出鏡率,相信一般情況下都會選擇Spring MVC。
REST的成熟度模型中,第三層就是HATEOAS,Spring目前還提供了Spring Hateoas子項目,對鏈接、資源等方面的支持都做了一定的增強。
馬鈞:我目前在實際項目中使用的是Spray,這是一個開源的 REST/HTTP 工具包和底層網路 IO 包,基於 Scala 和 Akka 構建。輕量級、非同步、非堵塞、基於 actor 模式、模塊化和可測試是Spray的特點。
InfoQ:HTTP2.0規范正在制定當中,您對它的期待是什麼?
李錕:我的期待包括兩個方面:應該做的和不應該做的。
HTTP/2.0規范應該做的:
與HTTP/1.1協議保持兼容。兼容的含義是說兩者可以並存,客戶端應用可以根據伺服器端的能力,自由地選擇使用HTTP/2.0還是HTTP/1.1,而且選擇過程對應用來說是透明的。
改進HTTP協議(作為資源的統一介面)之中操作語義表達方式的語法,提高網路傳輸效率。
更好地模塊化,這樣HTTP/2.0協議的實現能夠更好地模塊化。應用程序可根據需要選擇適當的模塊,而不是要麼全有、要麼全無。
廢棄掉HTTP/1.1協議中一些很少有人用到的部分,例如採用管道(pipelining)方式發送請求。
增加更多的動詞,以適應除CRUD之外的其他場景。
HTTP/2.0規范不應該做的:
HTTP/2.0協議不應該把底層的數據加密機制(即SSL)作為必選項。
HTTP/2.0協議不應該背離REST架構風格的約束,尤其是要確保操作語義對於中間組件的可見性。
在上面這兩個方面,Roy Fileidng曾經與SPDY協議設計者Mike Belshe發生過激烈爭論,詳情請看:Roy Fielding談Google SPDY協議
李建業:對此規范關注不多,不知道會不會有對於流的支持,目前我所知道的只有chunk方式進行簡單的支持,但是真正的流需要區分數據通道和控制通道——哪怕是邏輯上的區分,這樣就直接對REST風格產生了很大沖擊,考慮到流式服務在未來的發展潛力,我特別期待業界在這方面有所進展。
丁雪豐:HTTP 2.0很大程度上是借鑒了Google的SPDY,就我而言,首先,希望這個規范能做到與HTTP 1.1的兼容,使用者如果只認識1.1,那麼2.0能優雅「降級」;其次,希望2.0能帶來更好的性能,SPDY在這方面還是有所改進的,希望HTTP 2.0能再接再厲;最後,希望這個規范能在最終定稿時附帶一個最佳實踐,正確引導人們合理地使用HTTP 2.0。
馬鈞:沒研究過,估計即使出來,1.1還有很長的生命周期,不會很快被取代。
3. 淘寶客程序裡面Apicache是什麼dd呢怎麼傳到虛擬空間沒幾天,裡面就好多文件呢佔用了好多空間。
你說的是api,簡單說淘客程序通過api獲取淘客的數據
站上有訪問的話,程序就從淘寶獲取了數據,空間就有文件增加,但前提是你開啟了程序的緩存,
如果不開緩存的話,應該不會有文件保存到空間
幾百m空間不開緩存的話完全夠用,開緩存後訪問量大的話幾個G都不夠的
4. 如何更好的設計RESTful API
一個好的RESTful API,應該具備以下特徵:
這個API應該是對瀏覽器友好的,能夠很好地融入Web,而不是與Web格格不入。
1.瀏覽器是最常見和最通用的REST客戶端。好的RESTful API應該能夠使用瀏覽器+HTML完成所有的測試(不需要使用編程語言)。這樣的API還可以很方便地使用各種自動化的Web功能測試、性能測試工具來做測試。Web前端應用(基於瀏覽器的RIA應用、移動App等等)也可以很方便地將多個RESTful API的功能組合起來,建造Mashup類的應用。
這個API中所包含的資源和對於資源的操作,應該是直觀和容易理解的,並且符合HTTP協議的要求。
REST開發又被稱作「面向資源的開發」,這說明對於資源的抽象,是設計RESTful API的核心內容。RESTful API建模的過程與面向對象建模類似,是以名詞為核心的。這些名詞就是資源,任何可命名的抽象概念都可以定義為一個資源。而HTTP協議並不是一種傳輸協議,它實際提供了一個操作資源的統一介面。對於資源的任何操作,都應該映射到HTTP的幾個有限的方法(常用的有GET/POST/PUT/DELETE四個方法,還有不常用的PATCH/HEAD/OPTIONS方法)上面。所以RESTful API建模的過程,可以看作是具有統一介面約束的面向對象建模過程。
按照HTTP協議的規定,GET方法是安全且冪等的,POST方法是既不安全也不冪等的(可以用來作為所有寫操作的通配方法),PUT、DELETE方法都是不安全但冪等的。將對資源的操作合理映射到這四個方法上面,既不過度使用某個方法(例如過度使用GET方法或POST方法),也不添加過多的操作以至於HTTP的四個方法不夠用。
2.如果發現資源上的操作過多,以至於HTTP的方法不夠用,應該考慮設計出更多的資源。設計出更多資源(以及相應的URI)對於RESTful API來說並沒有什麼害處。
這個API應該是松耦合的。
RESTful API的設計包括了三個循序漸進、由低到高的層次:資源抽象、統一介面、超文本驅動。正是這三個層次確保了RESTful API的松耦合性。
3.當設計面向互聯網的API時,松耦合變成了一種「必須有」的強需求。緊耦合的API非常脆弱,一旦公布出去,伺服器端和客戶端都無法持續進化。尤其是伺服器端,公布出去的介面根本不敢改,改了之後,幾乎所有客戶端應用立即無法正常工作。REST這種架構風格就是緊耦合API的解毒劑,這個話題可以談的很深,這里就不展開了。感興趣的讀者可以參考《REST實戰》。
這個API中所使用的表述格式應該是常見的通用格式
在RESTful API中,對於資源的操作,是通過在伺服器端-客戶端之間傳遞資源的表述來間接完成的。資源的表述可以有很多種格式,並且在響應和請求中的資源表述格式也會有所不同。GET/POST響應中的資源表述格式,常見的有HTML、XML、JSON;POST/PUT請求中的資源表述格式,常見的有標準的HTML表單參數、XML、JSON。
4.這些常見表述格式,處理起來非常容易,有大量的框架和庫提供支持。所以除非有很合理的要求,通常不需要使用自定義的私有格式。
使用HTTP響應狀態代碼來表達各種出錯情況
HTTP響應狀態代碼,是HTTP協議這個統一介面中用來表達出錯情況的標准機制。響應狀態代碼分成兩部分:status code和reason phase。兩部分都是可定製的,也可以使用標準的status code,只定製reason phase。
5.如果一個所謂的「RESTful API」對於任何請求都返回200 OK響應,在響應的消息體中返回出錯情況信息,這種做法顯然不符合「確保操作語義的可見性」這個REST架構風格的基本要求。
這個API應該對於HTTP緩存是友好的
6.充分利用好HTTP緩存是RESTful API可伸縮性的根本。HTTP協議是一個分層的架構,從兩端的user agent到origin server之間,可以插入很多中間組件。而在整個HTTP通信鏈條的很多位置,都可以設置緩存。HTTP協議內建有很好的緩存機制,可以分成過期模型和驗證模型兩套緩存機制。如果API設計者完全沒有考慮過如何利用HTTP緩存,那麼這個API的可伸縮性會有很多問題。
5. 如何採用api方式進行全局緩存部署
使用gacutil.exe工具安裝:gacutil -i "要注冊的dll文件全路徑"。
"gacutil.exe」工具為.NET自帶工具 (C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin)
在開始運行中輸入"cmd」進入命令窗口,通過CD選擇到"gacutil.exe」文件所在的目錄,
或者 使用Visual Studio 命令提示符
如在命令行輸入: gacutil -i D:/Microsoft.SharePoint.dll
可以輸入『gacutil -?』查看幫助
6. 蘋果api怎麼清理內存緩存垃圾
清理緩存可以用同 步助 手會 比較安全,它會先進行全盤掃描,清理過程不會誤刪
7. Java緩存技術常用的有哪些
常見的java緩存框架有:
OSCache
OSCache是個一個廣泛採用的高性能的J2EE緩存框架,OSCache能用於任何Java應用程序的普通的緩存解決方案。
OSCache有以下特點:
緩存任何對象,你可以不受限制的緩存部分jsp頁面或HTTP請求,任何java對象都可以緩存。
擁有全面的API--OSCache API給你全面的程序來控制所有的OSCache特性。
永久緩存--緩存能隨意的寫入硬碟,因此允許昂貴的創建(expensive-to-create)數據來保持緩存,甚至能讓應用重啟。
8. win API串口 緩存問題~~~~~
COMSTAT comstat
ClearCommError(.......&comstat);
comstat.cbInQue就是接受緩沖區中位元組數量
9. 如何 服務全局緩存jsapi
我的工程里每2個小時自動啟動job獲取jsapi_ticket,accessToken等有時限的數據,獲取後緩存在memcached里,然後也更新在資料庫里,但每次讀取的時候都是從memcached里取,資料庫只是備查用的
10. 關於API Gateway cache的思考
API Gateway 需要緩存,以防止microservice無回應的時候提供緩存數據
不管後端服務是否健康,先訪問緩存。如果緩存存在直接返回緩存數據,如果不存在再訪問後端。優點是能大幅降低響應時間(cache vs network),缺點是會返回陳舊數據。是否採取這個方案取決於client對數據新鮮程度的要求。如果允許一定程度的陳舊數據,可以通過調整緩存過期時間來找到平衡。
後端服務失敗可以返回默認數據或者緩存數據。如果不允許默認數據,就得從緩存讀取緩存數據。但是,設置緩存的時候會設置過期時間,比如30秒。如果過期了緩存數據就不復存在,那系統就會不available。
在存儲緩存的時候,可以存一份緩存過期時間(比如一天)很長的備份緩存。如果後端服務失敗,operational緩存又過期,可以從備份緩存中讀取數據以保證服務的可用性。備份緩存可以在作業緩存更新的時候同步更新。