(更新时间)2021年5月28日 商城高并发秒杀系统(.NET Core版) 06-注册中心组件的封装

网友投稿 472 2022-05-30

一:consul注册发现封装

///

/// consul服务发现实现 /// public class ConsulServiceDiscovery : AbstractServiceDiscovery { public ConsulServiceDiscovery(IOptions options) : base(options) { } /*public ConsulServiceDiscovery(IOptions options) { this.serviceDiscoveryOptions = options.Value; }*/ /*public List Discovery(string serviceName) { // 1.2、从远程服务器取 CatalogService[] queryResult = RemoteDiscovery(serviceName); var list = new List(); foreach (var service in queryResult) { list.Add(new ServiceNode { Url = service.ServiceAddress + ":" + service.ServicePort }); } return list; }*/ protected override CatalogService[] RemoteDiscovery(string serviceName) { // 1、创建consul客户端连接 2s 1、使用单例全局共享 2、使用数据缓存(进程:字典,集合) 3、使用连接池 var consulClient = new ConsulClient(configuration => { //1.1 建立客户端和服务端连接 configuration.Address = new Uri(serviceDiscoveryOptions.DiscoveryAddress); }); // 2、consul查询服务,根据具体的服务名称查询 var queryResult = consulClient.Catalog.Service(serviceName).Result; // 3、判断请求是否失败 if (!queryResult.StatusCode.Equals(HttpStatusCode.OK)) { throw new FrameException($"consul连接失败:{queryResult.StatusCode}"); } return queryResult.Response; } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

///

/// consul服务注册实现 /// public class ConsulServiceRegistry : IServiceRegistry { // 服务注册选项 public readonly ServiceRegistryOptions serviceRegistryOptions; public ConsulServiceRegistry(IOptions options) { this.serviceRegistryOptions = options.Value; } /// /// 注册服务 /// public void Register() { // 1、创建consul客户端连接 var consulClient = new ConsulClient(configuration => { //1.1 建立客户端和服务端连接 configuration.Address = new Uri(serviceRegistryOptions.RegistryAddress); }); // 2、获取 var uri = new Uri(serviceRegistryOptions.ServiceAddress); // 3、创建consul服务注册对象 var registration = new AgentServiceRegistration() { ID = string.IsNullOrEmpty(serviceRegistryOptions.ServiceId) ? Guid.NewGuid().ToString() : serviceRegistryOptions.ServiceId, Name = serviceRegistryOptions.ServiceName, Address = uri.Host, Port = uri.Port, Tags = serviceRegistryOptions.ServiceTags, Check = new AgentServiceCheck { // 3.1、consul健康检查超时间 Timeout = TimeSpan.FromSeconds(10), // 3.2、服务停止5秒后注销服务 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5), // 3.3、consul健康检查地址 HTTP = $"{uri.Scheme}://{uri.Host}:{uri.Port}{serviceRegistryOptions.HealthCheckAddress}", // 3.4 consul健康检查间隔时间 Interval = TimeSpan.FromSeconds(10), } }; // 4、注册服务 consulClient.Agent.ServiceRegister(registration).Wait(); Console.WriteLine($"服务注册成功:{serviceRegistryOptions.ServiceAddress}"); // 5、关闭连接 consulClient.Dispose(); } /// /// 注销服务 /// /// public void Deregister() { // 1、创建consul客户端连接 var consulClient = new ConsulClient(configuration => { //1.1 建立客户端和服务端连接 configuration.Address = new Uri(serviceRegistryOptions.RegistryAddress); }); // 2、注销服务 consulClient.Agent.ServiceDeregister(serviceRegistryOptions.ServiceId).Wait(); Console.WriteLine($"服务注销成功:{serviceRegistryOptions.ServiceAddress}"); // 3、关闭连接 consulClient.Dispose(); } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

二:配置选项

///

/// 服务发现选项 /// public class ServiceDiscoveryOptions { public ServiceDiscoveryOptions() { // 默认地址 this.DiscoveryAddress = "http://localhost:8500"; } /// /// 服务发现地址 /// public string DiscoveryAddress { set; get; } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

///

/// 节点注册选项 /// public class ServiceRegistryOptions { public ServiceRegistryOptions() { this.ServiceId = Guid.NewGuid().ToString(); this.RegistryAddress = "http://localhost:8500"; this.HealthCheckAddress = "/HealthCheck"; } // 服务ID public string ServiceId { get; set; } // 服务名称 public string ServiceName { get; set; } // 服务地址http://localhost:5001 public string ServiceAddress { get; set; } // 服务标签(版本) public string[] ServiceTags { set; get; } /*// 服务地址(可以选填 === 默认加载启动路径(localhost)) public string ServiceAddress { set; get; } // 服务端口号(可以选填 === 默认加载启动路径端口) public int ServicePort { set; get; } // Https 或者 http public string ServiceScheme { get; set; }*/ // 服务注册地址 public string RegistryAddress { get; set; } // 服务健康检查地址 public string HealthCheckAddress { get; set; } }

1

2

3

4

5

6

7

8

9

10

11

12

(更新时间)2021年5月28日 商城高并发秒杀系统(.NET Core版) 06-注册中心组件的封装

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

三:consul相关扩展

///

/// 服务发现IOC容器扩展 /// public static class ServiceDiscoveryServiceCollectionExtensions { // consul服务发现 public static IServiceCollection AddServiceDiscovery(this IServiceCollection services) { // 1、注册consul服务发现 AddServiceDiscovery(services, options => { }); return services; } public static IServiceCollection AddServiceDiscovery(this IServiceCollection services, Action options) { // 2、注册到IOC容器 services.Configure(options); // 3、注册consul服务发现 services.AddSingleton(); return services; } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

///

/// 微服务注册扩展 /// public static class ServiceRegistryApplicationBuilderExtensions { public static IApplicationBuilder UseRegistry(this IApplicationBuilder app) { // 1、从IOC容器中获取Consul服务注册配置 var serviceNode = app.ApplicationServices.GetRequiredService>().Value; // 2、获取应用程序生命周期 var lifetime = app.ApplicationServices.GetRequiredService(); // 2.1 获取服务注册实例 var serviceRegistry = app.ApplicationServices.GetRequiredService(); // 3、获取服务地址 var features = app.Properties["server.Features"] as FeatureCollection; var address = features.Get().Addresses.First(); var uri = new Uri(address); // 4、注册服务 serviceNode.Id = Guid.NewGuid().ToString(); //serviceNode.Address = $"{uri.Scheme}://{uri.Host}"; serviceNode.Address = uri.Host; serviceNode.Port = uri.Port; serviceNode.HealthCheckAddress = $"{uri.Scheme}://{uri.Host}:{uri.Port}{serviceNode.HealthCheckAddress}"; serviceRegistry.Register(serviceNode); // 5、服务器关闭时注销服务 lifetime.ApplicationStopping.Register(() => { serviceRegistry.Deregister(serviceNode); }); return app; } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

///

/// 服务注册IOC容器扩展 /// public static class ServiceRegistryServiceCollectionExtensions { // consul服务注册 public static IServiceCollection AddServiceRegistry(this IServiceCollection services) { AddServiceRegistry(services, optons => { }); return services; } // consul服务注册 public static IServiceCollection AddServiceRegistry(this IServiceCollection services, Action options) { // 1、配置选项到IOC services.Configure(options); // 2、注册consul注册 services.AddSingleton(); // 3、注册开机自动注册服务 services.AddHostedService(); return services; } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

四:相关依赖的类文件

///

/// 服务url /// public class ServiceUrl { public string Url { set; get; } }

1

2

3

4

5

6

7

///

/// 服务启动时自动注册 /// public class ServiceRegistryIHostedService : IHostedService { private readonly IServiceRegistry serviceRegistry; public ServiceRegistryIHostedService(IServiceRegistry serviceRegistry) { this.serviceRegistry = serviceRegistry; } public Task StartAsync(CancellationToken cancellationToken) { /* // 1、从IOC容器中获取Consul服务注册配置 var serviceNode = app.ApplicationServices.GetRequiredService>().Value; // 2、获取应用程序生命周期 var lifetime = app.ApplicationServices.GetRequiredService(); // 2.1 获取服务注册实例 var serviceRegistry = app.ApplicationServices.GetRequiredService();*/ // 3、获取服务地址 /*var features = app.Properties["server.Features"] as FeatureCollection; var address = features.Get().Addresses.First();*/ //var uri = new Uri(address); // 4、注册服务 /* serviceNode.Id = Guid.NewGuid().ToString(); //serviceNode.Address = $"{uri.Scheme}://{uri.Host}"; serviceNode.Address = uri.Host; serviceNode.Port = uri.Port; serviceNode.HealthCheckAddress = $"{uri.Scheme}://{uri.Host}:{uri.Port}{serviceNode.HealthCheckAddress}";*/ return Task.Run(() => serviceRegistry.Register()); /*// 5、服务器关闭时注销服务 lifetime.ApplicationStopping.Register(() => { serviceRegistry.Deregister(serviceNode); });*/ } /// /// 服务停止时注销 /// /// /// public Task StopAsync(CancellationToken cancellationToken) { serviceRegistry.Deregister(); return Task.CompletedTask; } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

///

/// 服务注册节点 /// public class ServiceRegistryConfig { public ServiceRegistryConfig() { this.Id = Guid.NewGuid().ToString(); this.Name = ""; this.Address = this.RegistryAddress = "http://localhost:8500"; this.HealthCheckAddress = ""; } // 服务ID public string Id { get; set; } // 服务名称 public string Name { get; set; } // 服务标签(版本) public string[] Tags { set; get; } // 服务地址(可以选填 === 默认加载启动路径(localhost)) public string Address { set; get; } // 服务端口号(可以选填 === 默认加载启动路径端口) public int Port { set; get; } // 服务注册地址 public string RegistryAddress { get; set; } // 服务健康检查地址 public string HealthCheckAddress { get; set; } }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

///

/// 服务Node,将所有服务抽象为Node /// public class ServiceNode { public string Url { set; get; } }

1

2

3

4

5

6

7

///

/// 服务发现配置 /// public class ServiceDiscoveryConfig { /// /// 服务注册地址 /// public string RegistryAddress { set; get; } }

1

2

3

4

5

6

7

8

9

10

///

/// 服务注册 /// public interface IServiceRegistry { /// /// 注册服务 /// void Register(); /// /// 撤销服务 /// void Deregister(); }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

///

/// 服务发现 /// public interface IServiceDiscovery { /// /// 服务发现 /// /// 服务名称 /// List Discovery(string serviceName); }

1

2

3

4

5

6

7

8

9

10

11

12

///

/// 抽象服务发现,主要是缓存功能 /// public abstract class AbstractServiceDiscovery : IServiceDiscovery { // 字典缓存 private readonly Dictionary> CacheConsulResult = new Dictionary>(); protected readonly ServiceDiscoveryOptions serviceDiscoveryOptions; public AbstractServiceDiscovery(IOptions options) { this.serviceDiscoveryOptions = options.Value; // 1、创建consul客户端连接 var consulClient = new ConsulClient(configuration => { //1.1 建立客户端和服务端连接 configuration.Address = new Uri(serviceDiscoveryOptions.DiscoveryAddress); }); // 2、consul 先查询服务 var queryResult = consulClient.Catalog.Services().Result; if (!queryResult.StatusCode.Equals(HttpStatusCode.OK)) { throw new FrameException($"consul连接失败:{queryResult.StatusCode}"); } // 3、获取服务下的所有实例 foreach (var item in queryResult.Response) { QueryResult result = consulClient.Catalog.Service(item.Key).Result; if (!queryResult.StatusCode.Equals(HttpStatusCode.OK)) { throw new FrameException($"consul连接失败:{queryResult.StatusCode}"); } var list = new List(); foreach (var service in result.Response) { list.Add(new ServiceNode { Url = service.ServiceAddress + ":" + service.ServicePort }); } CacheConsulResult.Add(item.Key, list); } } public List Discovery(string serviceName) { // 1、从缓存中查询consulj结果 if (CacheConsulResult.ContainsKey(serviceName)) { return CacheConsulResult[serviceName]; } else { // 1.2、从远程服务器取 CatalogService[] queryResult = RemoteDiscovery(serviceName); var list = new List(); foreach (var service in queryResult) { list.Add(new ServiceNode { Url = service.ServiceAddress + ":" + service.ServicePort }); } // 1.3 将结果添加到缓存 CacheConsulResult.Add(serviceName, list); return list; } } /// /// 远程服务发现 /// /// /// protected abstract CatalogService[] RemoteDiscovery(string serviceName); }

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

.NET

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:在shiro基础上整合jwt,可在项目中直接使用呦
下一篇:由生产者/消费者问题看JAVA多线程
相关文章

 发表评论

暂时没有评论,来抢沙发吧~