分类 C# 下的文章

添加 API 目录,添加 WebApi 控制器,如果不能访问:
在 App_Start 目录下添加 WebApiConfig.cs:

using System.Web.Http;

namespace pc530.App_Start
{

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

}

Global.asax 中,Application_Start 添加一行:
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

安装net 6.0环境几种方式:

一、直接用源安装

On Ubuntu 20.04

wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb

On Ubuntu 18.04

wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb

开发SDK

apt update
apt install -y apt-transport-https
apt install -y dotnet-sdk-6.0

应用程序运行时

apt update
apt install -y apt-transport-https
apt install -y aspnetcore-runtime-6.0

ASP.NET Core Runtime

apt update
apt install -y apt-transport-https
apt install -y dotnet-runtime-6.0

二、官方脚本

wget https://dot.net/v1/dotnet-install.sh
chmod +x dotnet-install.sh
./dotnet-install.sh -c 6.0

增加变量:
$ vim ~/.bashrc
export PATH=$PATH:$HOME/.dotnet
export DOTNET_ROOT=$HOME/.dotnet
source ~/.bashrc

三、用 Snap 安装

apt install snapd
systemctl enable --now snapd.socket
systemctl enable --now snapd apparmor
snap install dotnet-sdk --classic --channel=6.0
snap alias dotnet-sdk.dotnet dotnet
snap install dotnet-runtime-60 --classic
snap alias dotnet-runtime-60.dotnet dotnet
vim ~/.bashrc
export DOTNET_ROOT=/snap/dotnet-sdk/current
source ~/.bashrc

开启 Tab 自动完成功能:

$ vim ~/.zshrc

# zsh parameter completion for the dotnet CLI
_dotnet_zsh_complete()
{
  local completions=("$(dotnet complete "$words")")
  reply=( "${(ps:\n:)completions}" )
}
compctl -K _dotnet_zsh_complete dotnet

$source ~/.zshrc

$ vim ~/.bashrc

# bash parameter completion for the dotnet CLI
_dotnet_bash_complete()
{
  local word=${COMP_WORDS[COMP_CWORD]}

  local completions
  completions="$(dotnet complete --position "${COMP_POINT}" "${COMP_LINE}" 2>/dev/null)"
  if [ $? -ne 0 ]; then
    completions=""
  fi
  COMPREPLY=( $(compgen -W "$completions" -- "$word") )
}
complete -f -F _dotnet_bash_complete dotnet

$ source ~/.bashrc

测试:

dotnet new console --output testapp1
dotnet run --project testapp1

打包时,选择 linux

安装SVN:

apt install subversion
svn checkout https://server/myproject
cd myproject
chmod 777 ./myproject

后台运行

nohup ./myproject> /dev/null 2>&1 &

web 项目后台运行:

nohup dotnet Demo.Net.Core.dll --urls="http://:8081;http://:8082" --environment=Delopment > /dev/null 2>&1 &

注意,后台运行时,不能用 ReadKey, ReadLine 之类的方法,会导致一行动就出错退出。

ASP.NET可用的线程毕竟是有限的,可能是当时瞬间的并发请求太多,ASP.NET来不及创建足够的线程处理这些请求。

我们来看一下.Net framework中线程相关的设置

machine.config中的processModel(位于C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config)

有4个相关设置:maxWorkerThreads(默认值是20), maxIoThreads(默认值是20), minWorkerThreads(默认值是1), minIoThreads(默认值是1)。(这些设置是针对每个CPU核)

我们用的就是默认设置,由于我们的Web服务器是8核的,于是实际的maxWorkerThreads是160,实际的maxIoThreads是160,实际的minWorkerThreads是8,实际的minIoThreads是8。

基于这样的设置,是不是如果瞬间并发请求是169,就会出现排队?不是的,ASP.NET没这么傻!因为CLR 1秒只能创建2个线程("The CLR ThreadPool injects new threads at a rate of about 2 per second. "),等线程用完时才创建,黄花菜都凉了。
我们猜测ASP.NET只是根据这个设置去预测线程池中的可用线程是不是紧张,是不是需要创建新的线程,以及创建多少线程。

假如并发请求数平时是300,突然某个瞬间并发请求数是600,超出了ASP.NET预估的所需的可用线程数,于是那些拿不到线程的请求只能排队等待正在执行的请求释放线程以及CLR创建新的线程。
随着时间的推移,释放出来的线程+新创建的线程足以处理这些排队的请求,就恢复了正常。

优化设置

<processModel enable="true"  requestQueueLimit="5000" maxWorkerThreads="2000" maxIoThreads="1000" minWorkerThreads="150" minIoThreads="150"/>

先申请 ssl 证书,导入到IIS服务器证书中,记下证书指纹

netsh http add sslcert ipport=0.0.0.0:5008 certhash=A209A62D46FFE7AAB32E05612B93655EE531F605 appid={3df26ced-2230-4b33-bd7c-bf2774231d65}

certhash 是证书指纹,appid 是程序的 appid,

显示已使用的:
netsh http show sslcert

要更新证书,先删除SSL证书绑定:
netsh http delete sslcert ipport=0.0.0.0:5008