As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.
Executando vários aplicativos e aplicativos ASP.NET principais com um manifesto de implantação
É possível usar um manifesto de implantação para informar o Elastic Beanstalk como implantar a aplicação. Ao usar esse método, você não MSDeploy precisa gerar um pacote de origem para um único ASP.NET aplicativo executado no caminho raiz do seu site. Em vez disso, você pode usar um arquivo de manifesto para executar várias aplicações em caminhos diferentes. Ou, alternativamente, você pode pedir ao Elastic Beanstalk que implante e execute o aplicativo com o Core. ASP.NET Também é possível usar um manifesto de implantação para configurar um grupo de aplicações para executar suas aplicações.
Os manifestos de implantação adicionam suporte para aplicações .NET Core ao Elastic Beanstalk. Você pode implantar uma aplicação .NET Framework sem um manifesto de implantação. No entanto, as aplicações .NET Core exigem um manifesto de implantação para execução no Elastic Beanstalk. Ao usar um manifesto de implantação, você cria um arquivo do site para cada aplicação e, em seguida, empacota os arquivos do site em um segundo arquivo ZIP que contém o manifesto de implantação.
Os manifestos de implantação também adicionam a capacidade de executar vários aplicativos em diferentes caminhos. Um manifesto de implantação define um conjunto de alvos de implantação, cada um com um arquivamento do site e um caminho em que o IIS deve executá-lo. Por exemplo, você pode executar uma API da Web no caminho /api para atender a solicitações assíncronas e um aplicativo web no caminho raiz que consome a API.
É possível usar um manifesto de implantação para configurar sites do IIS com vinculações personalizadas e caminhos físicos. Isso permite configurar sites que recepcionam portas ou nomes de host específicos antes de implantar aplicações.
Você também pode usar um manifesto de implantação para executar várias aplicações usando grupos de aplicações no IIS ou no Kestrel. Você pode configurar um grupo de aplicativos para reiniciar seus aplicativos periodicamente, executar aplicativos de 32 bits ou usar uma versão específica do runtime do .NET Framework.
Para uma personalização completa, você pode escrever seus próprios scripts de implantação no Windows PowerShell e informar ao Elastic Beanstalk quais scripts executar para instalar, desinstalar e reiniciar seu aplicativo.
Os manifestos de implantação e os recursos relacionados exigem uma plataforma do Windows Server versão 1.2.0 ou posterior.
Para obter informações detalhadas sobre todas as opções de configuração, propriedades e recursos avançados disponíveis, como ignorar redefinições do IIS, consulte a referência do esquema do manifesto de implantação.
Seções
Aplicativos .NET Core
É possível usar um manifesto de implantação para executar aplicações .NET Core no Elastic Beanstalk. .NET Core é uma versão multiplataforma do .NET que é fornecida com uma ferramenta de linha de comando (dotnet). Você pode usá-lo para gerar uma aplicação, executá-lo localmente e prepará-lo para publicação.
Para executar uma aplicação .NET Core no Elastic Beanstalk, execute dotnet publish e empacote a saída em um arquivo ZIP, sem incluir os diretórios. Coloque o arquivo do site em um pacote de origem com um manifesto de implantação com um destino de implantação do tipo aspNetCoreWeb.
O seguinte manifesto de implantação executa um aplicativo .NET Core em um arquivo de site chamado dotnet-core-app.zip no caminho raiz.
exemplo aws-windows-deployment-manifest.json – .NET Core
{
"manifestVersion": 1,
"deployments": {
"aspNetCoreWeb": [
{
"name": "my-dotnet-core-app",
"parameters": {
"archive": "dotnet-core-app.zip",
"iisPath": "/"
}
}
]
}
}Inclua o arquivo de manifesto e de site em um arquivo ZIP para criar um pacote de origem.
exemplo dotnet-core-bundle.zip
.
|-- aws-windows-deployment-manifest.json
`-- dotnet-core-app.zip
O arquivo do site contém o código do aplicativo compilado, as dependências e o arquivo web.config.
exemplo dotnet-core-app.zip
.
|-- Microsoft.AspNetCore.Hosting.Abstractions.dll
|-- Microsoft.AspNetCore.Hosting.Server.Abstractions.dll
|-- Microsoft.AspNetCore.Hosting.dll
|-- Microsoft.AspNetCore.Http.Abstractions.dll
|-- Microsoft.AspNetCore.Http.Extensions.dll
|-- Microsoft.AspNetCore.Http.Features.dll
|-- Microsoft.AspNetCore.Http.dll
|-- Microsoft.AspNetCore.HttpOverrides.dll
|-- Microsoft.AspNetCore.Server.IISIntegration.dll
|-- Microsoft.AspNetCore.Server.Kestrel.dll
|-- Microsoft.AspNetCore.WebUtilities.dll
|-- Microsoft.Extensions.Configuration.Abstractions.dll
|-- Microsoft.Extensions.Configuration.EnvironmentVariables.dll
|-- Microsoft.Extensions.Configuration.dll
|-- Microsoft.Extensions.DependencyInjection.Abstractions.dll
|-- Microsoft.Extensions.DependencyInjection.dll
|-- Microsoft.Extensions.FileProviders.Abstractions.dll
|-- Microsoft.Extensions.FileProviders.Physical.dll
|-- Microsoft.Extensions.FileSystemGlobbing.dll
|-- Microsoft.Extensions.Logging.Abstractions.dll
|-- Microsoft.Extensions.Logging.dll
|-- Microsoft.Extensions.ObjectPool.dll
|-- Microsoft.Extensions.Options.dll
|-- Microsoft.Extensions.PlatformAbstractions.dll
|-- Microsoft.Extensions.Primitives.dll
|-- Microsoft.Net.Http.Headers.dll
|-- System.Diagnostics.Contracts.dll
|-- System.Net.WebSockets.dll
|-- System.Text.Encodings.Web.dll
|-- dotnet-core-app.deps.json
|-- dotnet-core-app.dll
|-- dotnet-core-app.pdb
|-- dotnet-core-app.runtimeconfig.json
`-- web.configExecutar vários aplicativos
Você pode executar vários aplicativos com um manifesto de implantação definindo vários alvos de implantação.
O seguinte manifesto de implantação configura dois aplicativos .NET Core. A aplicação WebApiSampleApp implementa uma API simples da Web e atende a solicitações assíncronas no caminho /api. O aplicativo DotNetSampleApp é um aplicativo web que atende solicitações no caminho raiz.
exemplo aws-windows-deployment-manifest.json – vários aplicativos
{
"manifestVersion": 1,
"deployments": {
"aspNetCoreWeb": [
{
"name": "WebAPISample",
"parameters": {
"appBundle": "WebApiSampleApp.zip",
"iisPath": "/api"
}
},
{
"name": "DotNetSample",
"parameters": {
"appBundle": "DotNetSampleApp.zip",
"iisPath": "/"
}
}
]
}
}Um aplicativo de exemplo com vários aplicativos está disponível em:
-
Pacote de origem implantável - dotnet-multiapp-sample-bundle-v2.zip
-
Código-fonte - dotnet-multiapp-sample-source-v2.zip
Configurar sites do IIS
É possível configurar sites do IIS com vinculações personalizadas e caminhos físicos usando o manifesto de implantação. Isso é útil quando é necessário configurar sites que recepcionam em portas específicas, usam nomes de host personalizados ou veiculam conteúdo de diretórios específicos.
O manifesto de implantação a seguir configura um site personalizado do IIS que recepciona HTTP com um número de porta específico e um caminho físico personalizado:
exemplo aws-windows-deployment-manifest.json - Configuração do site do IIS
{
"manifestVersion": 1,
"iisConfig": {
"websites": [
{
"name": "MyCustomSite",
"physicalPath": "C:\inetpub\wwwroot\mysite",
"bindings": [
{
"protocol": "http",
"port": 8080,
"hostName": "mysite.local"
}
]
}
]
},
"deployments": {
"aspNetCoreWeb": [
{
"name": "my-dotnet-core-app",
"parameters": {
"appBundle": "dotnet-core-app.zip",
"iisWebSite": "MyCustomSite",
"iisPath": "/"
}
}
]
}
}Neste exemplo:
-
Um site chamado "MyCustomSite" é criado com um caminho físico personalizado
-
O site tem uma associação HTTP na porta 8080 com um nome de host específico
-
O aplicativo ASP.NET Core é implantado neste site personalizado usando o parâmetro
iisWebSite
Usar o Roteamento de solicitação de aplicação (ARR)
Os módulos de Roteamento de solicitação de aplicação (ARR) e Reescrita de URL estão pré-instalados e disponíveis nas AMIs do Elastic Beanstalk para Windows. Esses módulos permitem cenários avançados de roteamento e manipulação de URL por meio da configuração do IIS usando a configuração de ebextensions ou aplicações.
O exemplo a seguir mostra um manifesto de implantação simples que configura um site com uma porta personalizada, combinado com uma configuração ebextensions que configura o roteamento do ARR básico:
exemplo aws-windows-deployment-manifest.json - Configuração simples do ARR
{
"manifestVersion": 1,
"iisConfig": {
"websites": [
{
"name": "ARRSite",
"physicalPath": "C:\\inetpub\\wwwroot\\arrsite",
"bindings": [
{
"protocol": "http",
"port": 8080,
"hostName": "localhost"
}
]
}
]
},
"deployments": {
"aspNetCoreWeb": [
{
"name": "BackendApp",
"parameters": {
"appBundle": "backend-app.zip",
"iisWebSite": "ARRSite",
"iisPath": "/backend"
}
}
]
}
}A configuração do ARR é feita por meio de ebextensions. A configuração a seguir define as regras básicas de roteamento do ARR:
exemplo. ebextensions/arr-config.config - Configuração básica do ARR
files:
"C:\\temp\\configure-arr.ps1":
content: |
# Enable ARR proxy at server level
Set-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter 'system.webServer/proxy' -Name 'enabled' -Value 'True'
# Clear any existing global rules to avoid conflicts
Clear-WebConfiguration -PSPath 'MACHINE/WEBROOT/APPHOST' -Filter 'system.webServer/rewrite/globalRules'
# Add global rule to route all requests to backend
Add-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' `
-Filter 'system.webServer/rewrite/globalRules' `
-Name '.' `
-Value @{
name = 'Route_to_Backend'
stopProcessing = 'True'
match = @{ url = '^(?!backend/)(.*)' }
action = @{
type = 'Rewrite'
url = 'http://localhost:8080/backend/{R:1}'
}
}
container_commands:
01_configure_arr:
command: powershell -ExecutionPolicy Bypass -File "C:\\temp\\configure-arr.ps1"
waitAfterCompletion: 0Essa configuração cria um site na porta 8080 e configura o ARR para rotear todas as solicitações recebidas para a aplicação de backend executada nesse site.
Configurar grupos de aplicativos
Você pode oferecer suporte a várias aplicações no seu ambiente Windows. Duas abordagens estão disponíveis:
-
Você pode usar o modelo de hospedagem fora do processo com o servidor da web Kestrel. Com esse modelo, você configura várias aplicações para serem executadas em um grupo de aplicações.
-
Você pode usar o modelo de hospedagem em andamento. Com esse modelo, você usa vários pools de aplicativos para executar vários aplicativos com apenas um aplicativo em cada pool. Se você estiver usando o servidor IIS e precisar executar várias aplicações, deverá usar essa abordagem.
Para configurar o Kestrel para executar várias aplicações em um grupo de aplicações, adicione hostingModel="OutofProcess" ao arquivo web.config. Considere os seguintes exemplos:
exemplo web.config - para o modelo de hospedagem fora do processo do Kestrel
<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add
name="aspNetCore"
path="*" verb="*"
modules="AspNetCoreModuleV2"
resourceType="Unspecified" />
</handlers>
<aspNetCore
processPath="dotnet"
arguments=".\CoreWebApp-5-0.dll"
stdoutLogEnabled="false"
stdoutLogFile=".\logs\stdout"
hostingModel="OutofProcess" />
</system.webServer>
</location>
</configuration>exemplo aws-windows-deployment-manifest.json – várias aplicações
{
"manifestVersion": 1,
"deployments": {"msDeploy": [
{"name": "Web-app1",
"parameters": {"archive": "site1.zip",
"iisPath": "/"
}
},
{"name": "Web-app2",
"parameters": {"archive": "site2.zip",
"iisPath": "/app2"
}
}
]
}
}O IIS não suporta várias aplicações em um grupo de aplicações porque ele usa o modelo de hospedagem no processo. Portanto, você precisa configurar várias aplicações atribuindo cada aplicação a um grupo de aplicações. Em outras palavras, atribua apenas uma aplicação a um grupo de aplicações.
Você pode configurar o IIS para usar grupos de aplicações diferentes no arquivo aws-windows-deployment-manifest.json. Faça as seguintes atualizações conforme você se refere ao próximo arquivo de exemplo:
-
Adicione uma
iisConfigseção que inclua uma subseção chamadaappPools. -
No bloco
appPools, liste os grupos de aplicações. -
Na seção
deployments, defina uma seçãoparameterspara cada aplicação. -
Para cada aplicação, a seção
parametersespecifica um arquivo, um caminho para executá-la e umappPoolno qual executá-la.
O manifesto de implantação a seguir configura dois grupos de aplicações que reiniciam sua aplicação a cada 10 minutos. Eles também anexam suas aplicações a uma aplicação web .NET Framework que é executada no caminho especificado.
exemplo aws-windows-deployment-manifest.json - uma aplicação por grupo de aplicações
{
"manifestVersion": 1,
"iisConfig": {"appPools": [
{"name": "MyFirstPool",
"recycling": {"regularTimeInterval": 10}
},
{"name": "MySecondPool",
"recycling": {"regularTimeInterval": 10}
}
]
},
"deployments": {"msDeploy": [
{"name": "Web-app1",
"parameters": {
"archive": "site1.zip",
"iisPath": "/",
"appPool": "MyFirstPool"
}
},
{"name": "Web-app2",
"parameters": {
"archive": "site2.zip",
"iisPath": "/app2",
"appPool": "MySecondPool"
}
}
]
}
}Definir implantações personalizadas
Para controle ainda maior, você pode personalizar totalmente a implantação de um aplicativo definindo uma implantação personalizada. Com uma implantação personalizada, o Elastic Beanstalk executa somente os PowerShell scripts que você fornece — ele não executa o gerenciamento do IIS em seu nome. Isso difere das msDeploy aspNetCoreWeb implantações, nas quais o Elastic Beanstalk interrompe automaticamente o IIS antes da instalação, o inicia depois e o reinicia quando necessário. Para uma implantação personalizada, seus scripts colocam o conteúdo do aplicativo, configuram o ambiente (por exemplo, IIS) e reiniciam o aplicativo.
Importante
Em um ambiente de servidor web com balanceamento de carga, o Elastic Beanstalk verifica a integridade da instância solicitando o caminho de verificação de integridade do ambiente (/por padrão) na porta 80. Algo deve seguir esse caminho, ou o ambiente se tornará insalubre mesmo que cada script de implantação seja bem-sucedido — uma causa comum de uma implantação personalizada que é concluída sem erros, mas deixa o ambiente em vermelho. Para uma implantação personalizada independente, sirva seu aplicativo a partir da raiz do site padrão. É válido colocar um aplicativo personalizado em um subcaminho quando outra implantação já serve o caminho de verificação de integridade, por exemplo, em um manifesto de vários aplicativos. Para obter mais informações sobre a integridade do ambiente, consulte Monitoramento de ambientes.
Uma implantação personalizada define até três scripts. A tabela a seguir descreve cada script, quando o Elastic Beanstalk o executa e o que seu script deve fazer.
| Script | Quando o Elastic Beanstalk o executa | Responsabilidade |
|---|---|---|
uninstall |
Antes da instalação de cada nova versão do aplicativo, ou seja, antes da implantação de cada aplicativo. | Pare o serviço ou remova os arquivos da versão anterior. |
install |
Durante a implantação de cada aplicativo. | Implante arquivos, configure o IIS ou seu serviço e forneça o aplicativo no caminho da verificação de integridade. |
restart |
Depois de cada implantação do aplicativo e após cada alteração na configuração. Se você definir comotrue, skipIISReset o Elastic Beanstalk ignora esse script em implantações de aplicativos, mas ainda o executa em alterações de configuração. A escolha de Reiniciar o App Server executa um nível de plataforma iisreset e não invoca seu script de reinicialização personalizado. |
Reinicie o IIS (iisreset) ou seu serviço para que a nova versão esteja ativa. |
Esses scripts também são executados sempre que o Elastic Beanstalk implanta seu aplicativo em uma instância recém-lançada — por exemplo, durante a criação inicial do ambiente e quando o Auto Scaling adiciona uma instância (scale-out) — porque cada nova instância instala o aplicativo à medida que ele é inicializado.
O manifesto de implantação a seguir instrui o Elastic Beanstalk a executar PowerShell scripts no modo de 32 bits. Ele especifica um install script (install.ps1), um restart script (restart.ps1) e um uninstall script (uninstall.ps1). O uninstall script é configurado ignoreErrors true para que a primeira implantação, quando não há nada para remover, não falhe.
exemplo aws-windows-deployment-manifest.json – implantação personalizada
{
"manifestVersion": 1,
"deployments": {
"custom": [
{
"name": "Custom site",
"architecture": 32,
"scripts": {
"install": {
"file": "install.ps1"
},
"restart": {
"file": "restart.ps1"
},
"uninstall": {
"file": "uninstall.ps1",
"ignoreErrors": true
}
}
}
]
}
}Inclua todos os artefatos necessários para executar o aplicativo em seu pacote de origem com o manifesto e os scripts. O Elastic Beanstalk não extrai esses artefatos para uma implantação personalizada — seus scripts devem extraí-los. No exemplo a seguir, o conteúdo do aplicativo é empacotado comoMyApp.zip.
exemplo Custom-site-bundle.zip
.
|-- aws-windows-deployment-manifest.json
|-- install.ps1
|-- restart.ps1
|-- uninstall.ps1
`-- MyApp.zip
Os scripts a seguir mostram uma implantação personalizada completa e correta da verificação de integridade de um aplicativo. IIS-hosted O install.ps1 script extrai o conteúdo do aplicativo e aponta o caminho físico do site padrão para ele, de forma que o aplicativo seja servido a partir do caminho raiz (/) em que a verificação de integridade é examinada.
exemplo instalar.ps1
$ErrorActionPreference = "Stop"
$appPath = "C:\inetpub\MyApp"
if (Test-Path $appPath) { Remove-Item $appPath -Recurse -Force }
# Elastic Beanstalk doesn't extract your bundle for custom deployments, so extract it yourself.
# MyApp.zip ships in the bundle, alongside this script. Resolve it relative to the script's
# own location so the path is reliable regardless of the current working directory.
$scriptDir = if ($PSScriptRoot) { $PSScriptRoot } else { (Get-Location).Path }
$bundleZip = Join-Path $scriptDir "MyApp.zip"
Add-Type -AssemblyName "System.IO.Compression.FileSystem"
[IO.Compression.ZipFile]::ExtractToDirectory($bundleZip, $appPath)
# Serve from the Default Web Site root ("/"), where the health check looks.
Import-Module WebAdministration
Set-ItemProperty "IIS:\Sites\Default Web Site" -Name physicalPath -Value $appPath
iisreset.exe /restart
if ($LASTEXITCODE -ne 0) { exit 1 }exemplo reinicie.ps1
$ErrorActionPreference = "Stop"
iisreset.exe /restart
if ($LASTEXITCODE -ne 0) { exit 1 }exemplo desinstalar.ps1
# Stop IIS first. While the site is live, w3wp holds locks on files under the app directory,
# which would make the following removal fail.
iisreset.exe /stop | Out-Null
Remove-Item "C:\inetpub\MyApp" -Recurse -Force -ErrorAction SilentlyContinueLembre-se dos seguintes pontos ao escrever scripts de implantação personalizados:
-
Siga o caminho da verificação de saúde. Aponte o caminho físico do site padrão para seu aplicativo ou implante no caminho da verificação de integridade, para que a verificação de integridade seja bem-sucedida.
-
Inclua um documento padrão. Se a raiz do site não tiver um documento padrão,
GET /retornará HTTP 403 e a verificação de integridade falhará. Envie umweb.configarquivo que defina um<defaultDocument>elemento ou nomeie sua página de destino para corresponder a um nome de documento padrão do IIS, comoDefault.htmouindex.htm. -
Reinicie o IIS você mesmo. Como o Elastic Beanstalk não executa o gerenciamento do IIS para implantações personalizadas, seus scripts devem ser executados para que as alterações entrem em
iisresetvigor. -
Localize os arquivos agrupados em relação ao script. O Elastic Beanstalk extrai seus scripts e artefatos agrupados no mesmo diretório. Resolva os arquivos agrupados em
$PSScriptRoot(a pasta que contém o script em execução) em vez de assumir um diretório de trabalho atual específico. -
Faça com que as falhas falhem na implantação. Defina
$ErrorActionPreference = "Stop"e verifique$LASTEXITCODEapós os comandos externos. Caso contrário, um script quebrado pode sair com êxito, e o Elastic Beanstalk trata a implantação como bem-sucedida, mesmo que o aplicativo não esteja sendo executado corretamente.
Exemplo: um serviço Windows auto-hospedado
Com uma implantação personalizada, você pode executar um serviço do Windows em vez de um IIS-hosted site. As plataformas Windows do Elastic Beanstalk não oferecem suporte ao nível do ambiente de trabalho. Em um ambiente com balanceamento de carga, o balanceador de carga verifica o caminho da verificação de integridade na porta 80, portanto, um serviço do Windows deve responder a essa solicitação para manter o ambiente saudável. O exemplo a seguir é um serviço auto-hospedado que escuta na própria porta 80 e, portanto, não precisa de um site complementar do IIS.
nota
Como as plataformas Windows não têm um nível de trabalho, um serviço somente em segundo plano ainda precisa responder à verificação de integridade em um ambiente com balanceamento de carga. Faça com que o serviço também responda ao caminho da verificação de integridade (conforme mostrado aqui) ou execute o trabalho em segundo plano em um site que o serve.
O manifesto executa os scripts no modo de 64 bits, correspondendo ao compilador C# de 64 bits usado para criar o serviço.
exemplo aws-windows-deployment-manifest.json - Serviço do Windows
{
"manifestVersion": 1,
"deployments": {
"custom": [
{
"name": "EbCustomService",
"architecture": 64,
"scripts": {
"install": {
"file": "serviceInstall.ps1"
},
"restart": {
"file": "serviceRestart.ps1"
},
"uninstall": {
"file": "serviceUninstall.ps1",
"ignoreErrors": true
}
}
}
]
}
}O pacote envia o manifesto, os três scripts, o código-fonte do serviço e um version.txt arquivo (cujo conteúdo é a string da versão, por exemplov1). O script de instalação compila o serviço na instância, então você não precisa de uma cadeia de ferramentas de compilação em seu pacote.
exemplo Custom-service-bundle.zip
.
|-- aws-windows-deployment-manifest.json
|-- EbCustomService.cs
|-- serviceInstall.ps1
|-- serviceRestart.ps1
|-- serviceUninstall.ps1
`-- version.txtO serviceInstall.ps1 script libera a porta 80 do IIS, compila o serviço da fonte incluída com o compilador C# embutido (csc.exe), o registra como um serviço e o inicia. LocalSystem Executar como LocalSystem permite que o serviço seja vinculado http://+:80/ sem uma reserva de URL ACL, o que mantém o exemplo mínimo. Na produção, prefira uma conta com menos privilégios, como NetworkService e conceda a ela a vinculação explicitamente com. netsh http add urlacl
exemplo serviço Install.ps1
# INSTALL: compile and register a self-hosted HTTP service that owns port 80.
$ErrorActionPreference = "Stop"
$svcName = "EbCustomService"
$appPath = "C:\CustomService"
$scriptDir = if ($PSScriptRoot) { $PSScriptRoot } else { (Get-Location).Path }
# Free port 80 from IIS and keep it from reclaiming the port on reboot.
Stop-Service W3SVC -Force -ErrorAction SilentlyContinue
Set-Service W3SVC -StartupType Manual -ErrorAction SilentlyContinue
# Fresh application directory.
if (Test-Path $appPath) { Remove-Item $appPath -Recurse -Force }
New-Item -ItemType Directory -Path $appPath | Out-Null
# Compile the service with the in-box .NET Framework compiler (no build tooling needed).
$csc = Join-Path $env:WINDIR "Microsoft.NET\Framework64\v4.0.30319\csc.exe"
$src = Join-Path $scriptDir "EbCustomService.cs"
$exe = Join-Path $appPath "EbCustomService.exe"
& $csc /nologo /target:exe /out:"$exe" /reference:System.ServiceProcess.dll "$src"
if ($LASTEXITCODE -ne 0) { exit 1 }
# Write the content served at "/". A real service would serve its own responses;
# here the install script writes a simple marker so the health check passes.
$version = (Get-Content (Join-Path $scriptDir "version.txt") -Raw).Trim()
Set-Content -Path (Join-Path $appPath "marker.txt") `
-Value "Custom service deployment $version succeeded" -NoNewline
# Register as a LocalSystem service so it can bind http://+:80/ without a URL ACL.
if (Get-Service $svcName -ErrorAction SilentlyContinue) {
Stop-Service $svcName -Force -ErrorAction SilentlyContinue
sc.exe delete $svcName | Out-Null
# sc.exe delete is async; poll until gone so New-Service below doesn't hit
# "service marked for deletion".
$deadline = (Get-Date).AddSeconds(30)
while ((Get-Service $svcName -ErrorAction SilentlyContinue) -and (Get-Date) -lt $deadline) {
Start-Sleep -Milliseconds 500
}
}
New-Service -Name $svcName -BinaryPathName "`"$exe`"" `
-DisplayName "EB Custom Service" -StartupType Automatic | Out-Null
Start-Service $svcNameO serviceRestart.ps1 script reinicia o serviço para que a nova versão fique ativa.
exemplo serviço Restart.ps1
# RESTART: restart the service so the new version becomes live.
$ErrorActionPreference = "Stop"
$svcName = "EbCustomService"
Restart-Service $svcName -ForceO serviceUninstall.ps1 script interrompe e exclui o serviço e remove os arquivos da versão anterior. O manifesto é definido como ignoreErrors true para esse script porque a primeira implantação não tem nenhuma versão anterior para remover.
exemplo serviço Uninstall.ps1
# UNINSTALL: stop and remove the previous version before the new install.
# The manifest sets ignoreErrors:true because the first deploy has nothing to remove.
$ErrorActionPreference = "Stop"
$svcName = "EbCustomService"
$appPath = "C:\CustomService"
if (Get-Service $svcName -ErrorAction SilentlyContinue) {
Stop-Service $svcName -Force -ErrorAction SilentlyContinue
sc.exe delete $svcName | Out-Null
# sc.exe delete is async; poll until the service is really gone so the next
# deploy's New-Service doesn't hit "service marked for deletion".
$deadline = (Get-Date).AddSeconds(30)
while ((Get-Service $svcName -ErrorAction SilentlyContinue) -and (Get-Date) -lt $deadline) {
Start-Sleep -Milliseconds 500
}
}
if (Test-Path $appPath) {
Remove-Item $appPath -Recurse -Force -ErrorAction SilentlyContinue
}O serviço em si é um pequeno programa em C# que hospeda um HttpListener on http://+:80/ e retorna uma resposta de texto paraGET /, que é o que satisfaz a verificação de integridade do balanceador de carga.
exemplo EbCustomService.cs
// Minimal self-hosted HTTP Windows service. Hosts an HttpListener on http://+:80/
// and answers the load balancer's GET "/" health check with the content that the
// install script wrote to marker.txt.
using System;
using System.IO;
using System.Net;
using System.ServiceProcess;
using System.Text;
using System.Threading;
namespace EbCustomService
{
public class MarkerService : ServiceBase
{
private const string Root = @"C:\CustomService";
private HttpListener _listener;
private Thread _worker;
private volatile bool _running;
public MarkerService()
{
this.ServiceName = "EbCustomService";
}
protected override void OnStart(string[] args)
{
_running = true;
_listener = new HttpListener();
_listener.Prefixes.Add("http://+:80/");
_listener.Start();
_worker = new Thread(Loop) { IsBackground = true };
_worker.Start();
}
protected override void OnStop()
{
_running = false;
try { if (_listener != null) _listener.Stop(); } catch { }
}
private void Loop()
{
while (_running)
{
HttpListenerContext ctx;
try { ctx = _listener.GetContext(); }
catch { break; }
try
{
byte[] buf = Encoding.UTF8.GetBytes(ReadFile(Path.Combine(Root, "marker.txt")));
ctx.Response.StatusCode = 200;
ctx.Response.ContentType = "text/plain";
ctx.Response.ContentLength64 = buf.Length;
ctx.Response.OutputStream.Write(buf, 0, buf.Length);
ctx.Response.OutputStream.Close();
}
catch { }
}
}
private static string ReadFile(string p)
{
try { return File.Exists(p) ? File.ReadAllText(p) : ""; }
catch { return ""; }
}
public static void Main()
{
ServiceBase.Run(new MarkerService());
}
}
}nota
Neste exemplo, a resposta fornecida / é um pequeno marcador de texto (marker.txt) que representa o conteúdo real do seu aplicativo. Em vez disso, um serviço de produção forneceria suas próprias respostas. Todo o resto desses scripts é o mínimo necessário para uma implantação personalizada do serviço Windows em funcionamento.