GitHub license
Commit
NuGet
MyGet (nightly builds)
NuGet Download
Bilibili
Hits

Project Introduction

The silky framework is designed to help developers quickly build a microservice application development framework through simple code and configuration under the .net platform.It provides RPC communication and Microservice Governance Two key capabilities. This means that the microservices developed using silky will have mutual remote discovery and communication capabilities. At the same time, using the rich service governance capabilities provided by silky, service governance demands such as service discovery, load balancing, and traffic scheduling can be realized. At the same time, silky is highly extensible, and users can customize their own implementation at almost any function point to change the default behavior of the framework to meet their own business needs.

The silky microservice has the following advantages:

  • out of the box

    • Simple and easy to use, use a general-purpose host or a web host to build (host) microservice applications.
    • Ease of use is high, and the interface-oriented proxy feature can realize local transparent calls.
    • Rich in functions, most of the microservice governance capabilities can be realized based on native libraries or lightweight extensions.
  • Ultra-large-scale microservice cluster practice

    • A high-performance cross-process communication protocol, using the DotNetty communication framework to implement the RPC framework based on the interface proxy, providing high-performance proxy-based remote call capabilities, the service is based on the interface, and the underlying details of the remote call are shielded for developers.
    • In terms of address discovery and traffic management, it can easily support large-scale cluster instances.
  • Enterprise-level microservice governance capabilities

    • Through the service governance implemented by Polly, the fault tolerance of the service is improved.
    • A variety of built-in load balancing strategies can intelligently perceive the health status of downstream nodes, significantly reduce call delays, and improve system throughput.
    • Supports multiple registration center services, real-time perception of service instances going online and offline.
  • Guarantee of Data Consistency

    • Use TCC distributed transactions to ensure the final consistency of data.

frame properties

silky microservice framework.png

service engine

  • Responsible for the initialization process of the silky host
  • Responsible for module parsing, dependency management and loading
  • Service registration and resolution

Modular/plug-in design

  • There are dependencies between modules
  • Support plug-in loading module
  • Support plug-in loading application services

RPC communication

  • Use Dotnetty as the underlying communication component, use TCP as the communication protocol, and use long links to improve system throughput
  • Interface-based dynamic proxy
  • Support calling via template
  • Support JSON codec
  • Support cache interception during RPC communication to improve communication performance
  • RPC call monitoring

Service Governance

  • Service automatic registration and discovery, intelligent perception of service instances going online and offline
  • RPC call failed retry
  • Supports load balancing routing methods such as polling, random routing, and hash consistency, intelligently perceives the health status of downstream nodes, significantly reduces call delays, and improves system throughput.
  • Support HTTP current limit and RPC call current limit
  • Support fuse protection, when non-friendly exceptions occur n times, the fuse protection will be turned on
  • Support monitoring of RPC calls
  • Service degradation, called when the RPC call failsFabllbackThe specified method achieves the purpose of service fault tolerance
  • Prohibit services from external access through configuration support

Build via .net host

  • Build microservice applications using web hosting
  • Build Microservices Applications Using a Generic Host
  • Build microservice applications with websocket capabilities
  • Build the gateway application

security design

  • The gateway performs identity authentication and authentication in a unified manner
  • The rpc token is used to protect the RPC communication, ensuring that the external cannot directly access the rpc service
  • RPC communication supports ssl encryption

Various configuration methods

  • Support Json format configuration file
  • Support configuration files in Yaml format
  • Support Apollo as a configuration service center
  • use environment variables

link tracking

  • HTTP request
  • RPC call
  • TCC distributed transaction
  • Other (EFCore)…

Support for distributed transactions

  • In the process of RPC communication, the final consistency of data is guaranteed through the TCC distributed framework
  • Implemented using interceptor + TODO log
  • Use Redis as TODO log storage warehouse

Support websocket communication

  • Build websocket service through websocketsharp.core component
  • Handshake and talk with the front end through the gateway agent

getting Started

sample project

Silky.Hero authority management system

quick start

Basic services

Recommended Usedocker-composeInstall and deploy basic services.

  1. Install and deploy Zookeeper, copy and save docker-compose.zookeeper.yml to the local, and then install the Zookeeper service through the following command:
docker-compose -f docker-compose.zookeeper.yml up -d
  1. Install and deploy the redis cache service, copy and save docker-compose.redis.yml locally, and then install the redis service through the following command:
docker-compose -f docker-compose.redis.yml up -d

create gateway

  1. CreateEmpty WebApplicationproject namedGateway,InstallSilky.Agent.Hostpackage, and inProgram.csThe code for creating a managed gateway application host is added to the class;
using Gateway;

var hostBuilder = Host.CreateDefaultBuilder()
    .ConfigureSilkyGatewayDefaults(webHostBuilder => webHostBuilder.UseStartup<Startup>());
await hostBuilder.Build().RunAsync();
  1. addStartup.csclass, and add the following code;
namespace Gateway;

public class Startup
{
    public void ConfigureService(IServiceCollection services)
    {
        services.AddSilkyHttpServices()
            .AddRouting()
            .AddSwaggerDocuments()
            .AddMiniProfiler();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseSwaggerDocuments();
            app.UseMiniProfiler();
        }

        app.UseRouting();
        app.UseEndpoints(endpoints => { endpoints.MapSilkyRpcServices(); });
    }
}
  1. delete.jsonconfiguration file, and addappsetiings.yamlconfiguration file, and add the following configuration:
rpc:
  token: ypjdYOzNd4FwENJiEARMLWwK0v7QUHPW
 
registrycenter:
  type: Zookeeper
  connectionStrings: 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183;127.0.0.1:2184,127.0.0.1:2185,127.0.0.1:2186
distributedCache:
  redis:
    isEnabled: true
    configuration: 127.0.0.1:6379,defaultDatabase=0
  1. Run the gateway project, check the address where the http service runs (for example: https port is 7160), then open it through a browserhttps://127.0.0.1:7160/index.html swagger online documentation; when the application service is not added through business microservices, the swagger documentation does not have any interface:

noexistservice.png

Business Microservices

  1. Create a file namedDemoHostconsole project, installSilky.Agent.Hostpackage, and inProgram.csThe code to create a managed application host is added to the class;
using Microsoft.Extensions.Hosting;

var hostBuilder = Host.CreateDefaultBuilder().ConfigureSilkyGeneralHostDefaults();
await hostBuilder.Build().RunAsync();                      
  1. Addappsettings.yamlconfiguration file, and add the following configuration:
rpc:
  token: ypjdYOzNd4FwENJiEARMLWwK0v7QUHPW
  port: 2200
 
registrycenter:
  type: Zookeeper
  connectionStrings: 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183;127.0.0.1:2184,127.0.0.1:2185,127.0.0.1:2186

distributedCache:
  redis:
    isEnabled: true
    configuration: 127.0.0.1:6379,defaultDatabase=0
  1. Add a sample service and add a new folderhelloand addIHellAppServiceinterface:
[ServiceRoute]
public interface IHelloAppService
{
    Task<string> SayHi([FromQuery]string name);
}
  1. Add toHellAppServiceclass, and implementIHellAppServiceinterface:
public class HelloAppService : IHelloAppService
{
    public Task<string> SayHi(string name)
    {
        return Task.FromResult($"Hello {name ?? "World"}");
    }
}
  1. runDemoHostProject, and refresh the Swagger online document through the browser, you can see the following interface, and you can debug the webapi online through the swagger document:

helloservice.png

How to call between services

  1. By referring to the application interface class library of other microservice applications (other microservices can package the application interface into a nuget package, and install the nuget package of the application interface of other microservice applications through the nuget package), by constructing the injected interface, directly Using the method defined by the interface, the dynamic proxy generated by the interface can realize RPC communication with the service provider:

Example: PermissionManager.cs in Silky.Hero project

public class PermissionManager : IPermissionManager, IScopedDependency
{
    private readonly IUserAppService _userAppService;
    private readonly IRoleAppService _roleAppService;

    public PermissionManager(IUserAppService userAppService,
        IRoleAppService roleAppService)
    {
        _userAppService = userAppService;
        _roleAppService = roleAppService;
    }

    public async Task<ICollection<string>> GetUserRoleNamesAsync(long userId)
    {
        var userRoleOutput = await _userAppService.GetRolesAsync(userId);
        return userRoleOutput.RoleNames;
    }

    public async Task<ICollection<long>> GetUserRoleIdsAsync(long userId)
    {
        var userRoleIds = await _userAppService.GetRoleIdsAsync(userId);
        return userRoleIds;
    }

    public async Task<ICollection<string>> GetRolePermissionsAsync(long roleId)
    {
        var rolePermissions = await _roleAppService.GetPermissionsAsync(roleId);
        return rolePermissions;
    }
}
  1. Call the interface through the templateIInvokeTemplateThe provided API implements remote service calls, and the interface supports routing to specific service provider methods through service item Id or WebAPI;

For example: In the Silky.Hero project, the gateway’s authority authentication processor AuthorizationHandler passesIInvokeTemplateCall the permission service provided by the permission application service to determine whether the currently requested interface has access permission:


public class AuthorizationHandler : SilkyAuthorizationHandlerBase
{
    private readonly IInvokeTemplate _invokeTemplate;

    private const string CheckPermissionServiceEntryId =
        "Silky.Permission.Application.Contracts.Permission.IPermissionAppService.CheckPermissionAsync.permissionName_Get";

    private const string CheckRoleServiceEntryId =
        "Silky.Permission.Application.Contracts.Permission.IPermissionAppService.CheckRoleAsync.roleName_Get";

    public AuthorizationHandler(IInvokeTemplate invokeTemplate)
    {
        _invokeTemplate = invokeTemplate;
    }

    protected override async Task<bool> PolicyPipelineAsync(AuthorizationHandlerContext context,
        HttpContext httpContext,
        IAuthorizationRequirement requirement)
    {
        if (requirement is PermissionRequirement permissionRequirement)
        {
            if (EngineContext.Current.HostEnvironment.EnvironmentName == SilkyHeroConsts.DemoEnvironment &&
                httpContext.Request.Method != "GET")
            {
                throw new UserFriendlyException("演示环境不允许修改数据");
            }

            var serviceEntryDescriptor = httpContext.GetServiceEntryDescriptor();
            if (serviceEntryDescriptor.GetMetadata<bool>("IsSilkyAppService"))
            {
                // todo 
                return true;
            }

            return await _invokeTemplate.InvokeForObjectByServiceEntryId<bool>(CheckPermissionServiceEntryId,
                permissionRequirement.PermissionName);
        }

        return true;
    }

    protected override async Task<bool> PipelineAsync(AuthorizationHandlerContext context, HttpContext httpContext)
    {
        var serviceEntryDescriptor = httpContext.GetServiceEntryDescriptor();
        var roles = serviceEntryDescriptor
            .AuthorizeData
            .Where(p => !p.Roles.IsNullOrEmpty())
            .SelectMany(p => p.Roles?.Split(","))
            .ToList();
        foreach (var role in roles)
        {
            if (!await _invokeTemplate.InvokeForObjectByServiceEntryId<bool>(CheckRoleServiceEntryId, role))
            {
                return false;
            }
        }

        return true;
    }
}

Remark:

The advantage of using the template call method is that there is no need to refer to the application interface defined by other microservice applications between microservice applications, and the application and application are completely decoupled and independent of each other; the disadvantage is that it does not support the usage scenarios of distributed transactions;

Quickly create applications through project templates

silky provides templatessilky.appTemplates can quickly create applications, and developers can use modules to quickly create silky microservice applications after installing templates.


> dotnet new --install Silky.App.Template

Use project templates to create microservice applications.


PS> dotnet new silky.app -h
Silky App (C#)
作者: Liuhll

Usage:
  dotnet new silky.app [options] [模板选项]

Options:
  -n, --name <name>       正在创建的输出名称。如未指定名称,则使用输出目录的名称。
  -o, --output <output>   要放置生成的输出的位置。
  --dry-run               如果运行给定命令行将导致模板创建,则显示将发生情况的摘要。
  --force                 强制生成内容 (即使它会更改现有文件)。
  --no-update-check       在实例化模板时,禁用对模板包更新的检查。
  --project <project>     应用于上下文评估的项目。
  -lang, --language <C#>  指定要实例化的模板语言。
  --type <project>        指定要实例化的模板类型。

模板选项:
  -t, --param:type <param:type>  Set the silky host type, optional values: webhost, generalhost ,wshost, gateway
                                 类型: string
                                 默认: generalhost
  -do, --dockersupport           Add docker support for Silky
                                 类型: bool
                                 默认: true
  -r, --rpcport <rpcport>        Set the port for rpc listening
                                 类型: int
                                 默认: 2200
  -in, --infrastr                only include basic service orchestration files
                                 类型: bool
                                 默认: false
  -e, --env <env>                Set dotnet env
                                 类型: string
                                 默认: Development
  -m, --module                   Is it a module project
                                 类型: bool
                                 默认: false
  -p:i, --includeinfr            Whether to include the basic orchestration service.
                                 类型: bool

Example:


# 创建网关
> dotnet new silky.app -t gateway -n Silky.Gateway

# 创建业务微服务
> dotnet new silky.app -t generalhost -n Silky.Demo

contribute

  • One of the easiest ways to contribute is to discuss issues. You can also contribute code changes by submitting Pull Requests.

#Silky #framework #designed #developers #quickly #build #microservice #development #framework #simple #code #configuration #net #platform

Leave a Comment

Your email address will not be published. Required fields are marked *