Taurus.MVC 微服务框架 入门开发教程:项目部署:1、微服务应用程序常规部署实现多开,节点扩容。

系列目录:

本系列分为项目集成、项目部署、架构演进三个方向,后续会根据情况调整文章目录。

本系列第一篇:Taurus.MVC V3.0.3 微服务开源框架发布:让.NET 架构在大并发的演进过程更简单。

Taurus.MVC 微服务框架 入门开发教程:项目集成:1、服务端:注册中心、网关。

Taurus.MVC 微服务框架 入门开发教程:项目集成:2、客户端:ASP.NET(C#)编程语言项目集成:应用中心。

Taurus.MVC 微服务框架 入门开发教程:项目集成:3、客户端:其它编程语言项目集成:应用中心。

Taurus.MVC 微服务框架 入门开发教程:项目集成:4、默认安全认证与自定义安全认证。

Taurus.MVC 微服务框架 入门开发教程:项目部署:1、微服务应用程序常规部署实现多开,节点扩容。

Taurus.MVC 微服务框架 入门开发教程:项目部署:2、微服务应用程序Docker部署实现多开。

Taurus.MVC 微服务框架 入门开发教程:项目部署:3、微服务应用程序发布到Docker部署(上)。

Taurus.MVC 微服务框架 入门开发教程:项目部署:4、微服务应用程序发布到Docker部署(下)。

Taurus.MVC 微服务框架 入门开发教程:项目部署:5、微服务应用程序版本升级。

Taurus.MVC 微服务框架 入门开发教程:项目部署:6、让Kestrel支持绑定多个域名转发。

Taurus.MVC 微服务框架 入门开发教程:架构演进:1、从单应用程序简单过渡到负载均衡。

Taurus.MVC 微服务框架 入门开发教程:架构演进:2、负载均到模块拆分负载。

Taurus.MVC 微服务框架 入门开发教程:架构演进:3、模块拆分负载到多级负载均衡。

前言:

最近在写相关微服务教程时发现,要构建负载均衡,如果不做点其它处理:

对于同一台主机而言上的ASP.NET Core 应用程序而言,需要通过复制程序,才能运行多份应用运行。

对于ASP.NET Core发布的项目:

1、默认是绑定约定好的端口,因此程序无法多开。

2、将绑定端口设置为0,即随机端口,让程序允许多开。

不过仅是多开,还不够。

因为对于微服务程序,需要在程序启动时,自动将自身的访问地址告诉注册中心。

默认的随机端口,无法知晓自己的运行地址,便无法发送到注册中心去。

因此,需要提前获知运行的地址(给MicroService.App.RunUrl赋值,便于发送到注册中心)。

 

通过小小思考,可以先获取随机可用端口,再指定该端口,即可解决这个个问题。

下面看具体的实现:

1、修改配置文件,使用随机端口:

这里设置启动端口号,和绑定的端口号都为0,0即随机。

注册中心地址是固定的,因此直接写。

{
  "AppSettings": {
  
    "MicroService.Client.Name": "*",//注册所有模块
    "MicroService.Client.RegUrl": "//192.168.188.95:9999",//注册中心的地址,这是固定的
"MicroService.App.RunUrl": "//localhost:0",//设置当前运行的访问地址的随机端口0,代码运行时再替换该值 "Host": "//*:0"//监听端口为随机,代码运行时再替换该值 } }

接下来,需要在启动程序里,把0这个随机端口提前修改为可用端口,并做端口替换。

2、修改启动代码:.NET5、NET6、NET7…系列的:Program.cs

using Microsoft.AspNetCore.Server.Kestrel.Core;
using System.Net;
using System.Net.Sockets;

var builder = WebApplication.CreateBuilder(args);
string host = CYQ.Data.AppConfig.GetApp("Host");
string runUrl = Taurus.Core.MicroService.Config.AppRunUrl;
if (host.Contains(":0"))//随机端口
{
    TcpListener tl = new TcpListener(IPAddress.Any, 0);
    tl.Start();
    int port = ((IPEndPoint)tl.LocalEndpoint).Port;//获取随机可用端口
    tl.Stop();
    host = host.Replace(":0", ":" + port);//替换监听端口号
    if (runUrl.Contains(":0"))
    {
        Taurus.Core.MicroService.Config.AppRunUrl = runUrl.Replace(":0", ":" + port);//替换设置启动路径的端口号
    }
}
builder.WebHost.UseUrls(host);
builder.Services.AddHttpContext();
builder.Services.Configure<KestrelServerOptions>(x => x.AllowSynchronousIO = true).Configure<IISServerOptions>(x => x.AllowSynchronousIO = true);

var app = builder.Build();
app.UseHttpContext();
app.UseTaurusMvc(app.Environment);
app.Run();

这里,先产生可用的监听端口,再用这个端口号赋值后再监听。

3、修改启动代码:ASP.NET Core 2.N到3.N系列:Program.cs

代码是一样的:

using System;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using CYQ.Data;
using System.Net.Sockets;
using System.Net;
using Taurus.Core;

namespace Taurus.View
{
    public class Program
    {
        public static void Main(string[] args)
        {

            BuildWebHost(args).Run();

        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseUrls(GetUrl())
                .Build();
        public static string GetUrl()
        {
            string host = AppConfig.GetApp("Host");
            string runUrl = MicroService.Config.AppRunUrl;
            if (host.Contains(":0"))//随机端口
            {
                TcpListener tl = new TcpListener(IPAddress.Any, 0);
                tl.Start();
                int port = ((IPEndPoint)tl.LocalEndpoint).Port;//获取随机可用端口
                tl.Stop();
                host = host.Replace(":0", ":" + port);
                if (runUrl.Contains(":0"))
                {
                    MicroService.Config.AppRunUrl = runUrl.Replace(":0", ":" + port);//设置启动路径
                }
            }
            return host;
        }
    }
}

4、修改启动代码:再优化一下,实现跨主机:

在上面的配置中:

    "MicroService.App.RunUrl": "//localhost:0",//设置当前运行的访问地址的随机端口0,代码运行时再替换该值

如果指定了localhost,默认情况下,仅适合单主机运行,无法跨主机直接运行。

因此,代码可以再优化一下,把localhost替换成本机局域网IP:

public static string GetUrl()
        {
            string host = AppConfig.GetApp("Host");
            string runUrl = MicroService.Config.AppRunUrl;
            if (host.Contains(":0"))//随机端口
            {
                TcpListener tl = new TcpListener(IPAddress.Any, 0);
                tl.Start();
                int port = ((IPEndPoint)tl.LocalEndpoint).Port;//获取随机可用端口
                tl.Stop();
                host = host.Replace(":0", ":" + port);
                if (runUrl.Contains(":0"))
                {
                    runUrl = runUrl.Replace(":0", ":" + port);//替换启动路径
                }
                if (runUrl.Contains("localhost"))//替换成内网IP
                {
                    System.Net.IPAddress[] addressList = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
                    foreach (var address in addressList)
                    {
                        if (!address.ToString().Contains(":"))
                        {
                            runUrl = runUrl.Replace("localhost", address.ToString());//替换启动路径
                            break;
                        }
                    }

                }
                MicroService.Config.AppRunUrl = runUrl;

            }
            
            return host;
        }

总结:

通过以上配置,发布后的应用程序,可以在任何主机上实现多开N次,就可以增加N个节点。

随时随地实现节点的动态新增扩容。