nginx代理与负载均衡

2023-05-16

随着谷歌浏览器不断的改变https调用websocket和非https资源的策略,从谷歌大概70以后不允许https调用非https资源和ws的websocket。后面实现了wss解决谷歌这一策略的影响。随着谷歌到90后版本限制了私有证书的调用,导致最新浏览器又不能调用wss的websocket了。一方面是安保要求https传输,一方面是谷歌不断加严格https策略和证书策略,有好一段时间竟然有点难两全了。

最近想起在linux试nginx的反向代理可以代理url,然后它还有负载均衡的功能。可不可以给客户端运行个nginx把https代理为http。顺带也实现了负载均衡呢?

有几个问题需要验证:
1.windows的nginx部署是否麻烦?
2.windows的nginx包是否太大?

如果需要安装或者包太大那么不可行。前几天用nginx正好解决了http调用https润乾页面老是要信任证书的问题。整个windows的nginx包就几兆。而且不需要安装,运行也是后台的,所以符合需求。

那么就可以自己用C#写个负载均衡启动程序,程序设计流程如下。

在这里插入图片描述

实现控制台代码如下:

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Diagnostics;

namespace LISLoadBalance
{
    /// <summary>
    /// 实现负载均衡启动网站
    /// </summary>
    class Program
    {
        /// <summary>
        /// 程序入口
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //尝试启动nginx
            string openUrl = TryStartNginx();
            //打开本地地址
            if (openUrl != "")
            {
                OpenChromeUtil.OpenUrl(openUrl);
            }
            Environment.Exit(0);
        }

        /// <summary>
        /// 尝试打开nginx
        /// </summary>
        public static string TryStartNginx()
        {
            try
            {
                string nginxConfPath = "C:\\TRAK\\nginx\\conf\\nginx.conf";
                //不存在负载均衡文件就不打开
                if (!File.Exists(nginxConfPath))
                {
                    MessageBox.Show(nginxConfPath + "不存在!", "提示", MessageBoxButtons.OK);
                    return "";
                }
                //读取nginx配置
                string confStr = TxtUtil.ReadTxt(nginxConfPath);
                //从第一行取到配置更新地址
                string updateUrl = confStr.Split((char)13)[0];
                updateUrl = updateUrl.Replace("#", "");
                //本地打开的地址
                string openUrl = confStr.Split((char)13)[1];
                openUrl = openUrl.Replace("#", "").Replace((char)10 + "", "");
                //得到服务器的配置
                string confStrServer = GetServerConf(updateUrl);
                //服务配置变化之后停止niginx
                if (confStrServer != "" && confStrServer != confStr)
                {
                    //杀掉nginx进程
                    foreach (Process p in System.Diagnostics.Process.GetProcessesByName("nginx"))
                    {
                        try
                        {
                            p.Kill();
                            p.WaitForExit();
                        }
                        catch (Exception exp)
                        {
                            Console.WriteLine(exp.Message);
                            System.Diagnostics.EventLog.WriteEntry("AlchemySearch:KillProcess", exp.Message, System.Diagnostics.EventLogEntryType.Error);
                        }
                    }
                    //写入新的配置
                    TxtUtil.WriteTxt(nginxConfPath, confStrServer, true);
                }
                //没有启动nginx就启动
                bool hasStart = false;
                //检查nginx是否启动
                foreach (Process p in System.Diagnostics.Process.GetProcessesByName("nginx"))
                {
                    hasStart = true;
                }
                //没nginx启动就尝试启动
                if (hasStart == false)
                {
                    string nginxPath = "C:\\TRAK\\nginx\\nginx.exe";
                    if (File.Exists(nginxPath))
                    {
                        Process.Start(nginxPath);
                        System.Threading.Thread.Sleep(1000);
                    }
                    else
                    {
                        MessageBox.Show(nginxPath + "不存在!", "提示", MessageBoxButtons.OK);
                    }
                }
                return openUrl;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "提示", MessageBoxButtons.OK);
                return "";
            }
        }

        /// <summary>
        /// 得到服务器的配置
        /// </summary>
        /// <param name="updateUrl"></param>
        /// <returns></returns>
        private static string GetServerConf(string updateUrl)
        {
            HttpWebRequest request = null;
            try
            {
                if (updateUrl.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    request = WebRequest.Create(updateUrl) as HttpWebRequest;
                    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                    request.ProtocolVersion = HttpVersion.Version11;
                    // 这里设置了协议类型。
                    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
                    request.KeepAlive = false;
                    ServicePointManager.CheckCertificateRevocationList = true;
                    ServicePointManager.DefaultConnectionLimit = 100;
                    ServicePointManager.Expect100Continue = false;
                }
                else
                {
                    request = (HttpWebRequest)WebRequest.Create(updateUrl);
                }
                HttpWebResponse response = request.GetResponse() as HttpWebResponse;
                Stream responseStream = response.GetResponseStream();
                StreamReader myread = new StreamReader(responseStream);
                string serverStr = myread.ReadToEnd();
                responseStream.Close();
                return serverStr;
            }
            catch (Exception ex)
            {
                MessageBox.Show("从主站点获取nginx配置失败:" + ex.Message, "提示", MessageBoxButtons.OK);
                return "";
            }
        }


        /// <summary>
        /// 回调
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="certificate"></param>
        /// <param name="chain"></param>
        /// <param name="errors"></param>
        /// <returns></returns>
        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            //总是接受  
            return true;
        }


    }
}

OpenChromeUtil.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace LISLoadBalance
{
    /// <summary>
    /// 打开谷歌浏览器工具类
    /// </summary>
    public class OpenChromeUtil
    {
        /// <summary>
        /// 打开url
        /// </summary>
        /// <param name="loginPath"></param>
        public static void OpenUrl(string loginPath)
        {
            string chromePath = "";
            bool IsChrome = TryGetSoftwarePath("chrome", out chromePath);
            if (IsChrome && chromePath.Length > 0)
            {
                System.Diagnostics.Process.Start(chromePath, "--app="+loginPath);
            }
            else
            {
                Process pro = new Process();
                //文件路径
                pro.StartInfo.FileName = loginPath;
                pro.StartInfo.CreateNoWindow = true;
                pro.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                pro.StartInfo.Verb = "Open";
                pro.Start();
            }
        }

        /// <summary>
        /// 获取某个安装文件的执行路径
        /// </summary>
        /// <param name="softName">软件名</param>
        /// <param name="path">路径</param>
        /// <returns></returns>
        public static bool TryGetSoftwarePath(string softName, out string path)
        {
            string strPathResult = string.Empty;
            string strKeyName = "";     
            object objResult = null;

            Microsoft.Win32.RegistryValueKind regValueKind;
            Microsoft.Win32.RegistryKey regKey = null;
            Microsoft.Win32.RegistryKey regSubKey = null;

            try
            {
                //读取值
                regKey = Microsoft.Win32.Registry.LocalMachine;
                regSubKey = regKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + softName.ToString() + ".exe", false);

                //如果在LocalMachine获取不到,可以在CurrentUser里获取
                if (regSubKey == null)
                {
                    regKey = Microsoft.Win32.Registry.CurrentUser;
                    regSubKey = regKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\" + softName.ToString() + ".exe", false);
                }

                //读路径
                objResult = regSubKey.GetValue(strKeyName);
                regValueKind = regSubKey.GetValueKind(strKeyName);

                //设置路径
                if (regValueKind == Microsoft.Win32.RegistryValueKind.String)
                {
                    strPathResult = objResult.ToString();
                }
            }
            catch (System.Security.SecurityException ex)
            {
                path = "";
                MessageBox.Show("你没有读取注册表的权限! " + ex.Message, "提示", MessageBoxButtons.OK);
            }
            catch (Exception ex)
            {
                path = "";
                MessageBox.Show("读取注册表错误! " + ex.Message, "提示", MessageBoxButtons.OK);
            }
            finally
            {

                if (regKey != null)
                {
                    regKey.Close();
                    regKey = null;
                }

                if (regSubKey != null)
                {
                    regSubKey.Close();
                    regSubKey = null;
                }
            }

            if (strPathResult != string.Empty)
            {
                path = strPathResult;
                return true;
            }
            else
            {
                path = "";
                return false;
            }
        }
    }
}

TxtUtil.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace LISLoadBalance
{
    ///<summary  NoteObject="Class">
    /// [功能描述:文本工具类,提供文本操作] <para/>
    /// [创建者:zlz] <para/>
    /// [创建时间:2015年10月25日] <para/>
    ///<说明>
    ///  [说明:文本工具类,提供文本操作]<para/>
    ///</说明>
    ///<修改记录>
    ///    [修改时间:本次修改时间]<para/>
    ///    [修改内容:本次修改内容]<para/>
    ///</修改记录>
    ///<修改记录>
    ///    [修改时间:本次修改时间]<para/>
    ///    [修改内容:本次修改内容]<para/>
    ///</修改记录>
    ///</summary>
    public static class TxtUtil
    {
        /// <summary>
        /// 读取文件数据
        /// </summary>
        /// <param name="path">文件全路径</param>
        /// <returns></returns>
        public static string ReadTxt(string path)
        {
            //文件不存在
            if (!File.Exists(path))
            {
                return "";
            }
            FileStream fs = null;
            try
            {
                //要用不带BOM的utf8
                System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding(false);
                fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                StreamReader sr = new StreamReader(fs, utf8);
                string str = sr.ReadToEnd();
                return str;
            }
            catch (Exception ex)
            {
                MessageBox.Show("读文件异常:" + ex.Message, "提示", MessageBoxButtons.OK);
                return "";
            }
            finally
            {
                fs.Close();
            }
        }

        /// <summary>
        /// 写入数据到指定文件
        /// </summary>
        /// <param name="path">文件全路径</param>
        /// <param name="str">数据</param>
        /// <param name="isReplace">是否提换,默认为替换,否则为添加</param>
        /// <returns></returns>
        public static bool WriteTxt(string path, string str, bool isReplace = true, Encoding ecod = null)
        {
            if (ecod == null)
            {
                //要用不带BOM的utf8
                System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding(false);
                ecod = utf8;
            }
            FileStream fs = null;
            StreamWriter sw1 = null;
            try
            {
                //如果文件不存在,先创建一个
                if (!File.Exists(path))
                {
                    //创建写入文件  
                    fs = new FileStream(path, FileMode.Create, FileAccess.Write);
                    sw1 = new StreamWriter(fs, ecod);
                    //开始写入值  
                    sw1.WriteLine(str);
                }
                else
                {
                    //如果是替换,先清除之前的内容
                    if (isReplace)
                    {
                        using (StreamWriter sw = new StreamWriter(path, false, ecod))
                        {
                            sw.Write("");
                            sw.Close();
                        }
                    }
                    fs = new FileStream(path, FileMode.Append, FileAccess.Write);
                    sw1 = new StreamWriter(fs, ecod);
                    sw1.WriteLine(str);
                }
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show("读文件异常:" + ex.Message, "提示", MessageBoxButtons.OK);
                return false;
            }
            finally
            {
                if (sw1 != null)
                {
                    sw1.Close();
                }
                if (fs != null)
                {
                    fs.Close();
                }
            }
        }
    }
}

对nginx配置约定加上前两行注释,以实现自动从服务器更新配置。达到在服务器维护负载信息的目的。
在这里插入图片描述
维护时候就只要把主web的nginx配置这里维护可用的负载服务器地址就行。客户端启动器就能及时得的负载列表,驱动nginx负载调用。
在这里插入图片描述

搞完了之后把编译的启动器和nginx以前打包放入网站服务器,让初始化程序初始化到本地桌面即可
在这里插入图片描述

然后就可以通过负载启动程序驱动登录了。
在这里插入图片描述

在这里插入图片描述

哈哈,说干就干。此模式不需要依赖别的组提供负载均衡。直接自己内部就实现负载,何其美哉。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

nginx代理与负载均衡 的相关文章

随机推荐

  • C++定义全局类对象

    可能我这个全局类的说法不是很准确 xff0c 不过其实就是变量的扩展延伸 比如你想把一个类让全部的CPP都能用 xff0c 而不是一个变量 xff0c 那么需要这样定义 xff1a 假设有一个预编译头stdafx h 在stdafx h中加
  • Linux服务器VG扩容、LV扩容

    测试环境中K8s集群部署过程中发现磁盘大小太小 xff0c 需要对现有虚机的磁盘进行扩容 xff0c 计划 步骤1 虚机增加一块磁盘 步骤2 将磁盘添加到原有vg组中 步骤3 通过vg中资源给原有磁盘挂载目录进行lv扩容 实施步骤 xff1
  • Openstack云平台脚本部署之Neutron网络服务配置(九)

    目录 一 简介 二 部署脚本 2 1 网络节点独立部署 2 2 控制节点与网络节点融合部署 2 3 脚本详细介绍 三 参考文档 四 源码 五 系列文章 一 简介 Openstack网络服务Neutron主要负责网络连接任务 xff0c 包括
  • Android开发java调用C简单示例

    目录 下载NDK和CMake新建NDK项目写入C 43 43 代码 xff0c 并运行 本文使用的Android Studio版本是windows版Android Studio Bumblebee 2021 1 1 Patch 2 先看下最
  • 互联网单点登录集成方案

    为了迎合公司互联网化经营 xff0c 业务部门均纷纷上马了互联网的项目 xff0c 部门应用之间各自为政 xff0c 无法形成公司整体品牌效应 xff0c 以及影响用户体验 xff0c 故 xff0c 有了以下的单点登录集成方案 概述 整合
  • 【软件教程】如何让vscode连接ssh时记住密码

    准备软件 客户机安装vscode xff08 vscode官网https code visualstudio com xff09 客户机和服务器配置ssh xff0c 确保能够连接 VSCode ssh记住密码教程 一 在Client客户机
  • 车辆检测--DAVE: A Unified Framework for Fast Vehicle Detection and Annotation

    DAVE A Unified Framework for Fast Vehicle Detection and Annotation ECCV2016 本文使用深度学习进行车辆检测和属性学习 提出的系统为 Detection and Ann
  • 对抗学习用于目标检测--A-Fast-RCNN: Hard Positive Generation via Adversary for Object Detection

    A Fast RCNN Hard Positive Generation via Adversary for Object Detection CVPR 2017 Caffe code https github com xiaolonw a
  • 人脸识别--SphereFace: Deep Hypersphere Embedding for Face Recognition

    SphereFace Deep Hypersphere Embedding for Face Recognition CVPR2017 https github com wy1iu sphereface pytorch https gith
  • 运动相机检测无人机-- Detecting Flying Objects using a Single Moving Camera

    Detecting Flying Objects using a Single Moving Camera PAMI 2017 http cvlab epfl ch research unmanned detection https dri
  • [转载]Python SMTP发送邮件-smtplib模块

    在进入正题之前 xff0c 我们需要对一些基本内容有所了解 xff1a 常用的电子邮件协议有SMTP POP3 IMAP4 xff0c 它们都隶属于TCP IP协议簇 xff0c 默认状态下 xff0c 分别通过TCP端口25 110和14
  • c语言和c++有什么区别

    差不多是win98跟winXP的关系 C 43 43 是在C的基础上增加了新的理论 xff0c 玩出了新的花样 所以叫C加加 C是一个结构化语言 xff0c 它的重点在于算法和数据结构 C程序的设计首要考虑的是如何通过一个过程 xff0c
  • 梳理LVM逻辑卷管理,

    在Linux操作系统会时不时碰到卷有关的操作 xff0c 以下也是罗列了相关操作内容 xff0c 仅供参考 创建PV VG LV的方法 将各物理磁盘或分区的系统类型设为Linux LVM xff0c 其system ID为8e xff0c
  • 使用sqlyog连接 Mysql 出现1251错误

    使用sqlyog连接 Mysql 出现1251错误 简述 xff1a 1251 client does not support authentication protocol requested by server consider upg
  • 准备给ubuntu18.04安装杀毒软件

    如题 xff0c 电脑最近总出现些奇奇怪怪的小问题 xff0c 还是得装个杀毒软件 xff0c 看是不是中病毒了 输入sudo apt get install clamtk 安装完成后 xff0c 输入clamtk 即可 xff0e 卸载方
  • 使用Nginx代理地址

    DotNetCore在Linux发布时候 xff0c 由于不止一个产品组发布网站 xff0c 不像以前大家都用IIS的80发布网站 那么就存在大家抢80端口的情况 xff0c 为了让大家不比加上端口为此用Nginx代理URL实现网站地址代理
  • CentOS安装Cache数据库

    适用CentOS7 6 CentOS8上安装Intersystem公司的Cache数据库 xff0c 资料基本是空白 xff0c 分享一下 首先安装解压软件unzip和libicu xff0c 最小化安装的缺 xff0c 全安装的不缺 yu
  • Cache数据库之ECP搭建

    Cache作为非关系数据库 xff0c 其强大毋庸置疑 首先其Globle结构 xff0c 直接暴露的表Globel数据 xff0c 以及提供的M语言操作Globle达到的最优查询速度 ECP xff08 企业缓存协议 xff09 更是提供
  • Sebia电泳绘图

    Sebia这仪器真是个奇葩的存在 自己仪器有图不存文件 xff0c LIS要的话还得自己按数据绘制 还有蛋白电泳 固定电泳 画不画参考线等不同要求 xff08 奇葩的很 xff09 按理这种事不属于lis范围 xff0c 无奈国内lis太卷
  • nginx代理与负载均衡

    随着谷歌浏览器不断的改变https调用websocket和非https资源的策略 xff0c 从谷歌大概70以后不允许https调用非https资源和ws的websocket 后面实现了wss解决谷歌这一策略的影响 随着谷歌到90后版本限制