Skip to content

Commit

Permalink
优化GetEndpoints缓存并发问题
Browse files Browse the repository at this point in the history
  • Loading branch information
yilei committed Jul 15, 2021
1 parent e1bd838 commit d4ae9f7
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 89 deletions.
6 changes: 6 additions & 0 deletions Grpc.Extensions.sln
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AspNetCore3.0", "AspNetCore
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MathClientHost", "examples\CodeFirst\MathClientHost\MathClientHost.csproj", "{5B3DC8DC-AC90-4BF2-9E1C-DE46F9782160}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{C876F8C2-DCEB-4F0A-8E72-FE73E4BBDF58}"
ProjectSection(SolutionItems) = preProject
src\Directory.Build.props = src\Directory.Build.props
Makefile = Makefile
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down
23 changes: 23 additions & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Project>
<PropertyGroup Label="Common package properties">
<Authors>RabbitYi</Authors>
<Copyright>Copyright (c) RabbitYi contributors. </Copyright>
<PackageTags>grpc,dashboard,consul,micorservice,opentracing,polly</PackageTags>
<PackageProjectUrl>https://github.com/yileicn/Grpc.Extensions/</PackageProjectUrl>
<PackageIconUrl></PackageIconUrl>
<RepositoryUrl>https://github.com/yileicn/Grpc.Extensions/</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageReleaseNotes></PackageReleaseNotes>
<NoPackageAnalysis>true</NoPackageAnalysis>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>1.4.9</Version>
<Description>一个基于GRPC的简单微服务框架
1.服务注册和发现
2.服务自动负载均衡
3.服务端中件间(性能监控[日志],全局错误处理,手动熔断)
4.客户端中件间(认证,超时时间设置)
5.DashBoard(远程调用,手动熔断,日志输出控制)
6.Grpc CodeFirst</Description>
</PropertyGroup>
</Project>
16 changes: 0 additions & 16 deletions src/Grpc.Extension.Abstract/Grpc.Extension.Abstract.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,7 @@

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Version>1.4.7</Version>
<Authors>RabbitYi</Authors>
<Company></Company>
<PackageId>FM.Grpc.Extensions.Abstract</PackageId>
<RepositoryUrl>https://github.com/yileicn/Grpc.Extensions/</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageProjectUrl>https://github.com/yileicn/Grpc.Extensions/</PackageProjectUrl>
<PackageTags>grpc,dashboard,consul,micorservice,opentracing,polly</PackageTags>
<Description>一个基于GRPC的简单微服务框架
1.服务注册和发现
2.服务自动负载均衡
3.服务端中件间(性能监控[日志],全局错误处理,手动熔断)
4.客户端中件间(认证,超时时间设置)
5.DashBoard(远程调用,手动熔断,日志输出控制)
6.Grpc CodeFirst</Description>
<AssemblyVersion>1.4.7.1</AssemblyVersion>
<FileVersion>1.4.7.1</FileVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
Expand Down
14 changes: 0 additions & 14 deletions src/Grpc.Extension.AspNetCore/Grpc.Extension.AspNetCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,7 @@

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<Version>1.4.8</Version>
<PackageId>FM.Grpc.Extensions.AspNetCore</PackageId>
<Authors>RabbitYi</Authors>
<Description>一个基于GRPC的简单微服务框架
1.服务注册和发现
2.服务自动负载均衡
3.服务端中件间(性能监控[日志],全局错误处理,手动熔断)
4.客户端中件间(认证,超时时间设置)
5.DashBoard(远程调用,手动熔断,日志输出控制)
6.Grpc CodeFirst</Description>
<PackageProjectUrl>https://github.com/yileicn/Grpc.Extensions/</PackageProjectUrl>
<RepositoryUrl>https://github.com/yileicn/Grpc.Extensions/</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>grpc,dashboard,consul,micorservice,opentracing,polly</PackageTags>
<Product>Grpc.Extensions.AspNetCore</Product>
</PropertyGroup>

<ItemGroup>
Expand Down
16 changes: 0 additions & 16 deletions src/Grpc.Extension.Client/Grpc.Extension.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,6 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<PackageId>FM.Grpc.Extensions.Client</PackageId>
<Authors>RabbitYi</Authors>
<PackageProjectUrl>https://github.com/yileicn/Grpc.Extensions/</PackageProjectUrl>
<Description>一个基于GRPC的简单微服务框架
1.服务注册和发现
2.服务自动负载均衡
3.服务端中件间(性能监控[日志],全局错误处理,手动熔断)
4.客户端中件间(认证,超时时间设置)
5.DashBoard(远程调用,手动熔断,日志输出控制)
6.Grpc CodeFirst</Description>
<Company />
<Version>1.4.8</Version>
<RepositoryType>git</RepositoryType>
<PackageTags>grpc,dashboard,consul,micorservice,opentracing,polly</PackageTags>
<RepositoryUrl>https://github.com/yileicn/Grpc.Extensions/</RepositoryUrl>
<AssemblyVersion>1.4.8.0</AssemblyVersion>
<FileVersion>1.4.8.0</FileVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
Expand Down
8 changes: 2 additions & 6 deletions src/Grpc.Extension.Client/Internal/ChannelPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,15 @@ public async Task<Channel> GetChannel(string grpcServiceName)
private async Task<string> GetEndpoint(string serviceName, string dicoveryUrl, string serviceTag)
{
//获取健康的endpoints
var isCache = true;
var healthEndpoints = await _memoryCache.GetOrCreateAsync(serviceName, async cacheEntry =>
var healthEndpoints = await _memoryCache.GetOrCreateAtomicAsync(serviceName, cacheEntry =>
{
isCache = false;
//cacheEntry.SetAbsoluteExpiration(TimeSpan.FromSeconds(_grpcClientOptions.ServiceAddressCacheTime));
return await _serviceDiscovery.GetEndpoints(serviceName, dicoveryUrl, serviceTag);
return _serviceDiscovery.GetEndpoints(serviceName, dicoveryUrl, serviceTag);
});
if (healthEndpoints == null || healthEndpoints.Count == 0)
{
throw new InternalException(GrpcErrorCode.Internal,$"get endpoints from discovery of {serviceName} is null");
}
//只有重新拉取了健康结点才需要去关闭不健康的Channel
if (isCache == false) ShutdownErrorChannel(healthEndpoints, serviceName);

return _loadBalancer.SelectEndpoint(serviceName, healthEndpoints);
}
Expand Down
52 changes: 52 additions & 0 deletions src/Grpc.Extension.Common/Common/MemoryCacheExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Grpc.Extension.Common
{
/// <summary>
/// MemoryCacheExtensions(Thread Safe)
/// </summary>
public static class MemoryCacheExtensions
{
private static readonly LazyConcurrentDictionary<int, SemaphoreSlim> _semaphores = new LazyConcurrentDictionary<int, SemaphoreSlim>();

public static async Task<T> GetOrCreateAtomicAsync<T>(this IMemoryCache memoryCache, object key, Func<ICacheEntry, Task<T>> factory)
{
if (memoryCache.TryGetValue(key, out var value))
return (T)value;

var semaphoreKey = (memoryCache, key).GetHashCode();
var semaphore = GetSemaphore(semaphoreKey);

await semaphore.WaitAsync()
.ConfigureAwait(false);
try
{
if (!memoryCache.TryGetValue(key, out value))
{
var entry = memoryCache.CreateEntry(key);
value = await factory(entry);
entry.SetValue(value);
entry.Dispose();
return (T)value;
}

return (T)value;
}
finally
{
semaphore.Release();
}
}

private static SemaphoreSlim GetSemaphore(int semaphoreKey)
{
return _semaphores.GetOrAdd(semaphoreKey, k => new SemaphoreSlim(1));
}
}
}
10 changes: 1 addition & 9 deletions src/Grpc.Extension.Common/Grpc.Extension.Common.csproj
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Version>1.4.7</Version>
<PackageProjectUrl>https://github.com/yileicn/Grpc.Extensions/</PackageProjectUrl>
<RepositoryUrl>https://github.com/yileicn/Grpc.Extensions/</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>grpc,dashboard,consul,micorservice,opentracing,polly</PackageTags>
<Authors>RabbitYi</Authors>
<PackageId>FM.Grpc.Extensions.Common</PackageId>
<FileVersion>1.4.7.1</FileVersion>
<AssemblyVersion>1.4.7.1</AssemblyVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="AspectCore.Extensions.Reflection" Version="1.1.0" />
<PackageReference Include="Grpc.Core" Version="2.24.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.1.1" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
Expand Down
11 changes: 1 addition & 10 deletions src/Grpc.Extension.Discovery/Grpc.Extension.Discovery.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,8 @@

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Version>1.4.8</Version>
<PackageId>FM.Grpc.Extensions.Discovery</PackageId>
<Authors>RabbitYi</Authors>
<Description>默认使用Consul实现服务注册和服务发现</Description>
<PackageProjectUrl>https://github.com/yileicn/Grpc.Extensions/</PackageProjectUrl>
<RepositoryUrl>https://github.com/yileicn/Grpc.Extensions/</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>grpc,dashboard,consul,micorservice,opentracing,polly</PackageTags>
<Product>Grpc.Extension.Discovery</Product>
<AssemblyVersion>1.4.8.0</AssemblyVersion>
<FileVersion>1.4.8.0</FileVersion>
<Description>默认使用Consul实现服务注册和服务发现</Description>
</PropertyGroup>

<ItemGroup>
Expand Down
18 changes: 0 additions & 18 deletions src/Grpc.Extension/Grpc.Extension.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,7 @@

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Version>1.4.8</Version>
<Description>一个基于GRPC的简单微服务框架
1.服务注册和发现
2.服务自动负载均衡
3.服务端中件间(性能监控[日志],全局错误处理,手动熔断)
4.客户端中件间(认证,超时时间设置)
5.DashBoard(远程调用,手动熔断,日志输出控制)
6.Grpc CodeFirst</Description>
<Authors>RabbitYi</Authors>
<RepositoryUrl>https://github.com/yileicn/Grpc.Extensions/</RepositoryUrl>
<PackageId>FM.Grpc.Extensions</PackageId>
<Product>Grpc.Extensions</Product>
<Company></Company>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<AssemblyVersion>1.4.8.0</AssemblyVersion>
<FileVersion>1.4.8.0</FileVersion>
<RepositoryType>git</RepositoryType>
<PackageTags>grpc,dashboard,consul,micorservice,opentracing,polly</PackageTags>
<PackageProjectUrl>https://github.com/yileicn/Grpc.Extensions/</PackageProjectUrl>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
Expand Down

0 comments on commit d4ae9f7

Please sign in to comment.