Restful 採用 Http 進行通信,優勢是開放、標準、簡單、兼容性升級容易;html
缺點是性能略低。在 QPS 高或者對響應時間要求苛刻的服務上,能夠用 RPC(Remote Procedure Call),RPC 因爲採用二進制傳輸、TCP 通信,因此一般性能更好。java
.Net Core 下的 RPC(遠程方法調用)框架有 gRPC、Thrift 等,都支持主流的編程語言。linux
RPC 雖然效率略高,可是耦合性強,若是兼容性處理很差的話,一旦服務器端接口升級,客戶端就要更新,即便是增長一個參數,而 rest 則比較靈活。web
最佳實踐:對內一些性能要求高的場合用 RPC,對內其餘場合以及對外用 Rest。好比 web 服務器和視頻轉碼服務器之間通信能夠用 restful 就夠了,轉帳接口用 RPC 性能會更高一些。apache
Thrift架構編程
圖中,TProtocol(協議層),定義數據傳輸格式,例如:c#
TTransport(傳輸層),定義數據傳輸方式,能夠爲TCP/IP傳輸,內存共享或者文件共享等)被用做運行時庫。windows
Thrift支持的服務模型服務器
參考資料:http://www.javashuo.com/article/p-nvuouklh-bd.htmlrestful
把thrift-***.exe解壓到磁盤,更名爲thrift.exe(用起來方便一些)
namespace csharp RuPeng.ThriftTest1.Contract service UserService{ SaveResult Save(1:User user) User Get(1:i32 id) list<User> GetAll() } enum SaveResult { SUCCESS = 0, FAILED = 1, } struct User { 1: required i64 Id; 2: required string Name; 3: required i32 Age; 4: optional bool IsVIP; 5: optional string Remark; }
service定義的是服務類,enum 是枚舉,struct是傳入或者傳出的複雜數據類型(支持對象級聯)。
語法規範 http://thrift.apache.org/docs/idl
根據thrift語法生成C#代碼
cmd -> thrift.exe -gen csharp UserService.thrift
建立一個類庫項目 ThriftTest1.Contract,做爲客戶端和服務器之間的共用協議,把上一步生成的代碼放進項目。
ThriftTest1.Server項目引用ThriftTest1.Contract
建立項目:ApplicationExtenssion.cs
編寫實現類 UserServiceImpl.cs
public class UserServiceImpl : UserService.Iface { public User Get(int id) { User u = new User(); u.Id = id; u.Name = "用戶" + id; u.Age = 6; return u; } public List<User> GetAll() { List<User> list = new List<User>(); list.Add(new User { Id = 1, Name = "yzk", Age = 18, Remark = "hello" }); list.Add(new User { Id = 2, Name = "rupeng", Age = 6 }); return list; } public SaveResult Save(User user) { Console.WriteLine($"保存用戶,{user.Id}"); return SaveResult.SUCCESS; } }
修改Program下的Main函數 啓動服務器端
TServerTransport transport = new TServerSocket(8800);//監聽8800端口 var processor = new RuPeng.ThriftTest1.Contract.UserService.Processor(new UserServiceImpl());//設置實現類 TServer server = new TThreadPoolServer(processor, transport); server.Serve();
監聽8800端口
經過比較TSimpleServer、TThreadedServer、TThreadPoolServer,發現TSimpleServer只能同時響應一個客戶端,TThreadedServer則維護了一個clientQueue,clientQueue最大值是100,TThreadPoolServer則用的是用線程池響應多個客戶請求,生產環境毫不能用TSimpleServer。
調用方法
using (TTransport transport = new TSocket("localhost", 8800)) using (TProtocol protocol = new TBinaryProtocol(transport)) using (var clientUser = new UserService.Client(protocol)) { transport.Open(); User u = clientUser.Get(1); Console.WriteLine($"{u.Id},{u.Name}"); }
0.9.1以前只支持一個服務器一個服務,這也是建議的作法。以後支持多路服務在thrift中增長一個服務
修改UserService.thrift文件 添加如下內容 而後從新生成替換
service CalcService{ i32 Add(1:i32 i1,2:i32 i2) }
服務器:
1.建立CalcServiceImpl文件實現CalcService服務
2.修改Main方法以下:
TServerTransport transport = new TServerSocket(8800); var processorUserService = new RuPeng.ThriftTest1.Contract.UserService.Processor(new UserServiceImpl()) var processorCalcService = new RuPeng.ThriftTest1.Contract.CalcService.Processor(new CalcServiceImpl()); var processorMulti = new TMultiplexedProcessor(); processorMulti.RegisterProcessor("userService", processorUserService); processorMulti.RegisterProcessor("calcService", processorCalcService); TServer server = new TThreadPoolServer(processorMulti, transport); server.Serve();
客戶端:
using (TTransport transport = new TSocket("localhost", 8800)) using (TProtocol protocol = new TBinaryProtocol(transport)) using (var protocolUserService = new TMultiplexedProtocol(protocol, "userService")) using (var clientUser = new UserService.Client(protocolUserService)) using (var protocolCalcService = new TMultiplexedProtocol(protocol,"calcService")) using (var clientCalc = new CalcService.Client(protocolCalcService)) { transport.Open(); User u = clientUser.Get(1); Console.WriteLine($"{u.Id},{u.Name}"); Console.WriteLine(clientCalc.Add(1, 2)); }
原文地址:https://blog.csdn.net/qq_18145031/article/details/82802158