屁股侠 發表於 2022-9-24 00:40:00

.NET 反向代理 YARP 通过编码方式配置域名转发

<p>  前面介绍了 YARP 通过配置文件的方式配置代理转发(传送门),而众所周知,微软的一贯作风就是能通过配置文件做的事情,通过编码的方式也能实现!YARP 也不例外,废话不多说,直接上代码!</p>
<p>  首先,参照官方文档,我们先新建一个&nbsp;<span style="color: rgba(0, 128, 128, 1)">InMemoryConfigProvider</span> 类,并且继承&nbsp;<span style="color: rgba(0, 128, 128, 1)">IProxyConfigProvider</span> 接口,类里面还包含了一个&nbsp;&nbsp;<span style="color: rgba(0, 128, 128, 1)">IProxyConfig</span> 的类,别看漏了噢!</p>
<p>  这里多嘴一下,下面的代码出现了&nbsp;<span style="color: rgba(0, 0, 255, 1)">volatile</span> 关键字,介绍一下它:<span style="color: rgba(0, 0, 255, 1)">volatile</span> 是 C# 中用于控制同步的关键字,其意义是针对程序中一些敏感数据,不允许多线程同时访问,保证数据在任何访问时刻,最多有一个线程访问,以保证数据的完整性,<span style="color: rgba(0, 0, 255, 1)">volatile</span> 是修饰变量的修饰符。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> InMemoryConfigProvider : IProxyConfigProvider
{
    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">volatile</span><span style="color: rgba(0, 0, 0, 1)"> InMemoryConfig _config;

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> InMemoryConfigProvider(IReadOnlyList&lt;RouteConfig&gt; routes, IReadOnlyList&lt;ClusterConfig&gt;<span style="color: rgba(0, 0, 0, 1)"> clusters)
    {
      _config </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> InMemoryConfig(routes, clusters);
    }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> IProxyConfig GetConfig() =&gt;<span style="color: rgba(0, 0, 0, 1)"> _config;

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Update(IReadOnlyList&lt;RouteConfig&gt; routes, IReadOnlyList&lt;ClusterConfig&gt;<span style="color: rgba(0, 0, 0, 1)"> clusters)
    {
      </span><span style="color: rgba(0, 0, 255, 1)">var</span> oldConfig =<span style="color: rgba(0, 0, 0, 1)"> _config;
      _config </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> InMemoryConfig(routes, clusters);
      oldConfig.SignalChange();
    }

    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> InMemoryConfig : IProxyConfig
    {
      </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> CancellationTokenSource _cts = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">();

      </span><span style="color: rgba(0, 0, 255, 1)">public</span> InMemoryConfig(IReadOnlyList&lt;RouteConfig&gt; routes, IReadOnlyList&lt;ClusterConfig&gt;<span style="color: rgba(0, 0, 0, 1)"> clusters)
      {
            Routes </span>=<span style="color: rgba(0, 0, 0, 1)"> routes;
            Clusters </span>=<span style="color: rgba(0, 0, 0, 1)"> clusters;
            ChangeToken </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> CancellationChangeToken(_cts.Token);
      }

      </span><span style="color: rgba(0, 0, 255, 1)">public</span> IReadOnlyList&lt;RouteConfig&gt; Routes { <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">; }

      </span><span style="color: rgba(0, 0, 255, 1)">public</span> IReadOnlyList&lt;ClusterConfig&gt; Clusters { <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">; }

      </span><span style="color: rgba(0, 0, 255, 1)">public</span> IChangeToken ChangeToken { <span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">; }

      </span><span style="color: rgba(0, 0, 255, 1)">internal</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> SignalChange()
      {
            _cts.Cancel();
      }
    }
}</span></pre>
</div>
<p>&nbsp;</p>
<p>  然后添加一个扩展&nbsp;<span style="color: rgba(0, 128, 128, 1)">InMemoryConfigProviderExtensions</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> InMemoryConfigProviderExtensions
{
    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> IReverseProxyBuilder LoadFromMemory(<span style="color: rgba(0, 0, 255, 1)">this</span> IReverseProxyBuilder builder, IReadOnlyList&lt;RouteConfig&gt; routes, IReadOnlyList&lt;ClusterConfig&gt;<span style="color: rgba(0, 0, 0, 1)"> clusters)
    {
      builder.Services.AddSingleton</span>&lt;IProxyConfigProvider&gt;(<span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> InMemoryConfigProvider(routes, clusters));
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> builder;
    }
}</span></pre>
</div>
<p>&nbsp;</p>
<p>  接下来就是写配置了,我个人还是喜欢在配置文件中写,但是有动态配置需求的话,又不想登录服务器编辑 appsetting 文件,通过编码的方式确实更为方便,将配置写进库或者其它存储方式里面,那将是随心所欲啊!上代码:</p>
<p>Program.cs</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> routes = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">[]
{
    </span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> RouteConfig()
    {
      RouteId </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">admin</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
      ClusterId </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">admin</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
      Match </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> RouteMatch
      {
            Hosts </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">string</span>[] {<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">test1.ysmc.net.cn</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> },
            Path </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{**catch-all}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      }
    },

    </span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> RouteConfig()
    {
      RouteId </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">blazor</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
      ClusterId </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">blazor</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
      Match </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> RouteMatch
      {
            Hosts </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">string</span>[] {<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">test2.ysmc.net.cn</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> },
            Path </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{**catch-all}</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
      }
    }
};

</span><span style="color: rgba(0, 0, 255, 1)">var</span> clusters = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">[]
{
    </span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ClusterConfig()
    {
      ClusterId </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">admin</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
      LoadBalancingPolicy </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">RoundRobin</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
      Destinations </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> Dictionary&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>, DestinationConfig&gt;<span style="color: rgba(0, 0, 0, 1)">(StringComparer.OrdinalIgnoreCase)
      {
            { </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">admin</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">new</span> DestinationConfig() { Address = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">https://admin.blazor.zone</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> } }
      }
    },

    </span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> ClusterConfig()
    {
      ClusterId </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">blazor</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
      LoadBalancingPolicy </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">RoundRobin</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
      Destinations </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> Dictionary&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>, DestinationConfig&gt;<span style="color: rgba(0, 0, 0, 1)">(StringComparer.OrdinalIgnoreCase)
      {
            { </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">blazor</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">new</span> DestinationConfig() { Address = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">https://www.blazor.zone</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)"> } }
      }
    }
};

builder.Services.AddReverseProxy().LoadFromMemory(routes, clusters);</span></pre>
</div>
<p>  上面的配置代码,跟配置文件方式的节点和属性,都是对应的,照着写就是了</p>
<div class="cnblogs_code">
<pre>"ReverseProxy"<span style="color: rgba(0, 0, 0, 1)">: {
</span>"Routes"<span style="color: rgba(0, 0, 0, 1)">: {
    </span>"admin"<span style="color: rgba(0, 0, 0, 1)">: {
      </span>"ClusterId": "admin"<span style="color: rgba(0, 0, 0, 1)">,
      </span>"Match"<span style="color: rgba(0, 0, 0, 1)">: {
      </span>"Hosts": [ "test1.ysmc.net.cn"<span style="color: rgba(0, 0, 0, 1)"> ],
      </span>"Path": "{**catch-all}"<span style="color: rgba(0, 0, 0, 1)">
      }
    },
    </span>"blazor"<span style="color: rgba(0, 0, 0, 1)">: {
      </span>"ClusterId": "blazor"<span style="color: rgba(0, 0, 0, 1)">,
      </span>"Match"<span style="color: rgba(0, 0, 0, 1)">: {
      </span>"Hosts": [ "test2.ysmc.net.cn"<span style="color: rgba(0, 0, 0, 1)"> ],
      </span>"Path": "{**catch-all}"<span style="color: rgba(0, 0, 0, 1)">
      }
    }
},
</span>"Clusters"<span style="color: rgba(0, 0, 0, 1)">: {
    </span>"admin"<span style="color: rgba(0, 0, 0, 1)">: {
      </span>"LoadBalancingPolicy": "RoundRobin"<span style="color: rgba(0, 0, 0, 1)">,
      </span>"Destinations"<span style="color: rgba(0, 0, 0, 1)">: {
      </span>"admin"<span style="color: rgba(0, 0, 0, 1)">: {
          </span>"Address": "https://admin.blazor.zone/"<span style="color: rgba(0, 0, 0, 1)">
      }
      }
    },
    </span>"blazor"<span style="color: rgba(0, 0, 0, 1)">: {
      </span>"LoadBalancingPolicy": "RoundRobin"<span style="color: rgba(0, 0, 0, 1)">,
      </span>"Destinations"<span style="color: rgba(0, 0, 0, 1)">: {
      </span>"blazor"<span style="color: rgba(0, 0, 0, 1)">: {
          </span>"Address": "https://www.blazor.zone/"<span style="color: rgba(0, 0, 0, 1)">
      }
      }
    }
}
}</span></pre>
</div>
<p>&nbsp;</p>
<p>  最终效果还是依旧的完美,感谢大佬的观看,谢谢!</p>
<p><img src="https://img2022.cnblogs.com/blog/1897432/202209/1897432-20220924002841803-913899467.png" alt="" loading="lazy" style="display: block; margin-left: auto; margin-right: auto"></p>
<p>&nbsp;原文链接:https://www.cnblogs.com/ysmc/p/16724763.html</p>

</div>
<div id="MySignature" role="contentinfo">
    <p>本文来自博客园,作者:一事冇诚,转载请注明原文链接:https://www.cnblogs.com/ysmc/p/16724763.html</p><br><br>
来源:https://www.cnblogs.com/ysmc/p/16724763.html
頁: [1]
查看完整版本: .NET 反向代理 YARP 通过编码方式配置域名转发