1、Viper是什麼?
Viper 是.NET平台下的Anno微服務架構的一個示例項目。入門簡單、安全、穩定、高可用、全平台可監控。底層通訊可以随意切換
thrift
grpc
。 自帶服務發現、調用鍊追蹤、Cron 排程、限流、事件總線、CQRS 、DDD、類似MVC的開發體驗,插件化開發

github: https://github.com/duyanming/Viper
文檔位址: https://duyanming.github.io/
體驗位址: http://140.143.207.244/
如果對Viper不了解可以看:
1、 net core 微服務 快速開發架構 Viper 初體驗
2、打不死的小強 .net core 微服務 快速開發架構 Viper 限流
3、net core 微服務架構 Viper 調用鍊路追蹤
4、hello world .net core 微服務架構 Viper-01
2、Viper微服務編寫一個Hello World插件
前面章節我們已經建立好了一個HelloWorldService 服務,這一小節我們來編寫一個HelloWorld插件。啟動注冊中心
ViperCenter
修改
HelloWorldService
注冊中心位址。
2.1 建立一個HelloWorld插件
建立一個HelloWorld功能插件, 稍後我們以同樣的方式添加一個SoEasy功能插件。最後我們讓兩個插件互相調用并輸出結果。
添加Anno功能插件依賴
Install-Package Anno.EngineData -Version 1.0.2.6
增加一個插件啟動初始化配置類
HelloWorldBootStrap
using Anno.EngineData;
using System;
namespace Anno.Plugs.HelloWorldService
{
/// <summary>
/// 插件啟動引導器
/// DependsOn 依賴的類型程式集自動注入DI容器
/// </summary>
[DependsOn(
//typeof(Domain.Bootstrap)
//, typeof(QueryServices.Bootstrap)
//, typeof(Repository.Bootstrap)
//, typeof(Command.Handler.Bootstrap
)]
public class HelloWorldBootStrap : IPlugsConfigurationBootstrap
{
/// <summary>
/// Service 依賴注入建構之後調用
/// </summary>
public void ConfigurationBootstrap()
{
//throw new NotImplementedException();
}
/// <summary>
/// Service 依賴注入建構之前調用
/// </summary>
/// </summary>
public void PreConfigurationBootstrap()
{
//throw new NotImplementedException();
}
}
}
增加一個業務子產品
HelloWorldViperModule
/******************************************************
Writer:Du YanMing
Mail:[email protected]
Create Date:2020/10/30 13:15:24
Functional description: HelloWorldViperModule
******************************************************/
using System;
using System.Collections.Generic;
using System.Text;
namespace Anno.Plugs.HelloWorldService
{
using Anno.Const.Attribute;
using Anno.EngineData;
using HelloWorldDto;
public class HelloWorldViperModule: BaseModule
{
[AnnoInfo(Desc = "世界你好啊SayHi")]
public dynamic SayHello([AnnoInfo(Desc = "稱呼")] string name, [AnnoInfo(Desc = "年齡")] int age) {
Dictionary<string, string> input = new Dictionary<string, string>();
input.Add("vName",name);
input.Add("vAge", age.ToString());
var soEasyMsg = Newtonsoft.Json.JsonConvert.DeserializeObject<ActionResult<string>>(this.InvokeProcessor("Anno.Plugs.SoEasy", "AnnoSoEasy", "SayHi", input)).OutputData;
return new { HelloWorldViperMsg = $"{name}你好啊,今年{age}歲了", SoEasyMsg= soEasyMsg };
}
[AnnoInfo(Desc = "兩個整數相減等于幾?我來幫你算(x-y=?)")]
public int Subtraction([AnnoInfo(Desc = "整數X")] int x, [AnnoInfo(Desc = "整數Y")] int y)
{
return x - y;
}
[AnnoInfo(Desc = "買個商品吧,雙十一馬上就來了")]
public ProductDto BuyProduct([AnnoInfo(Desc = "商品名稱")] string productName, [AnnoInfo(Desc = "商品數量")] int number)
{
double price = new Random().Next(2, 90);
Dictionary<string, string> input = new Dictionary<string, string>();
input.Add("productName", productName);
input.Add("number", number.ToString());
var product = Newtonsoft.Json.JsonConvert.DeserializeObject<ActionResult<ProductDto>>(this.InvokeProcessor("Anno.Plugs.SoEasy", "AnnoSoEasy", "BuyProduct", input)).OutputData;
product.CountryOfOrigin = $"中國北京中轉--{ product.CountryOfOrigin}";
return product;
}
}
}
Anno.Plugs.SoEasyService
、
AnnoSoEasyModule
/******************************************************
Writer:Du YanMing
Mail:[email protected]
Create Date:2020/10/30 13:16:23
Functional description: AnnoSoEasyModule
******************************************************/
using Anno.EngineData;
using System;
using System.Collections.Generic;
using System.Text;
namespace Anno.Plugs.SoEasyService
{
using Anno.Const.Attribute;
using Anno.EngineData;
using HelloWorldDto;
public class AnnoSoEasyModule : BaseModule
{
[AnnoInfo(Desc = "AnnoSoEasy你好啊SayHi")]
public dynamic SayHi([AnnoInfo(Desc = "稱呼")] string vname, [AnnoInfo(Desc = "年齡")] int vage)
{
var msg = string.Empty;
if (vage < 12)
{
msg = "小朋友年紀輕輕就就開始玩變成了啊!加油Baby!";
}else if (vage < 23)
{
msg = "小兄弟,找女朋友了嗎?沒有的話趕緊找一個吧。别把心思都放在寫代碼上!";
}
else if (vage < 30)
{
msg = "兄弟,你家小孩幾歲了?開始學程式設計了嗎?";
}
else if (vage < 45)
{
msg = "大哥,你好能給我介紹個對象嗎?";
}
else if (vage < 55)
{
msg = "大叔,你家鄰居有小妹妹介紹嗎?";
}
else
{
msg = "還不退休?别寫代碼了!";
}
return $"{vname}:你好,我是SoEasy,{msg}";
}
[AnnoInfo(Desc = "兩個整數相加等于幾?我來幫你算")]
public int Add([AnnoInfo(Desc = "整數X")] int x, [AnnoInfo(Desc = "整數Y")] int y)
{
return x + y;
}
[AnnoInfo(Desc = "買個商品吧,雙十一馬上就來了")]
public ProductDto BuyProduct([AnnoInfo(Desc = "商品名稱")] string productName, [AnnoInfo(Desc = "商品數量")] int number)
{
double price = new Random().Next(2, 90);
return new ProductDto() { Name=productName,Price=price ,Number=number, CountryOfOrigin="中國台灣"};
}
}
}
至此兩個插件已經編寫完成,然後在上一章節中建立的 HelloWorldService 服務中引入我們編寫的兩個功能插件 Anno.Plugs.HelloWorldService、Anno.Plugs.SoEasyService。
啟動 HelloWorldService 服務
我們看到服務已經正常啟動,且已經成功注冊到注冊中心。下的章節我們一起來看一下Viper的 Api文檔 ,并且增加 全局過濾器、子產品過濾器、方法過濾器、異常過濾器、身份驗證顧慮器、如何增加請求緩存、單個服務如何限流、單個服務限流和Api網關限流之間的關系。
關于Viper的更多内容,随後更新。敬請關注。開源不易,感謝Star。