Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
Ejecución de varias aplicaciones y aplicaciones ASP.NET principales con un manifiesto de implementación
Puede utilizar un manifiesto de implementación para indicarle a Elastic Beanstalk cómo se va a implementar la aplicación. Al usar este método, no es necesario que lo utilices MSDeploy para generar un paquete de código fuente para una sola ASP.NET aplicación que se ejecute en la ruta raíz de tu sitio web. En su lugar, puede utilizar un archivo de manifiesto para ejecutar varias aplicaciones en rutas diferentes. O bien, puedes pedirle a Elastic Beanstalk que implemente y ejecute la aplicación con Core. ASP.NET También puede utilizar un manifiesto de implementación para configurar un grupo de aplicaciones en el que ejecutará las aplicaciones.
Los manifiestos de implementación añaden compatibilidad con las aplicaciones de .NET Core en Elastic Beanstalk. Puede implementar una aplicación.NET Framework sin un manifiesto de implementación. Sin embargo, las aplicaciones.NET Core requieren un manifiesto de implementación para ejecutarse en Elastic Beanstalk. Si utiliza un manifiesto de implementación, debe crear un archivo del sitio para cada aplicación y empaquetar todos ellos después en un segundo ZIP que contenga el manifiesto de implementación.
Los manifiestos de implementación también brindan la posibilidad de ejecutar varias aplicaciones en diferentes rutas. Un manifiesto de implementación define una serie de objetivos de implementación, cada uno de ellos con un archivo del sitio y una ruta en la que IIS debe ejecutarse. Por ejemplo, puede ejecutar una API web en la ruta /api para que atienda las solicitudes asincrónicas y una aplicación web en la ruta raíz que utilice la API.
Puede usar un manifiesto de implementación para configurar sitios web de IIS con enlaces personalizados y rutas físicas. Esto le permite configurar sitios web que escuchen los nombres de puertos o hosts específicos antes de implementar las aplicaciones.
También puede utilizar un manifiesto de implementación para ejecutar varias aplicaciones mediante grupos de aplicaciones en IIS o Kestrel. Puede configurar un grupo de aplicaciones para reiniciar las aplicaciones periódicamente, ejecutar aplicaciones de 32 bits o utilizar una versión específica del entorno de ejecución de .NET Framework.
Para una personalización completa, puede escribir sus propios scripts de implementación en Windows PowerShell e indicar a Elastic Beanstalk qué scripts debe ejecutar para instalar, desinstalar y reiniciar la aplicación.
El manifiesto de implementación y las características relacionadas requieren una plataforma de Windows Server versión 1.2.0 o posterior.
Para obtener información detallada sobre todas las opciones de configuración, propiedades y características avanzadas disponibles, como omitir los restablecimientos de IIS, consulte deployment manifest schema reference.
Secciones
Aplicaciones de .NET Core
Puede utilizar un manifiesto de implementación para ejecutar aplicaciones .NET Core en Elastic Beanstalk. .NET Core es una versión multiplataforma de .NET que incluye una herramienta de línea de comandos (dotnet). Puede utilizarla para generar una aplicación, ejecutarla localmente y prepararla para su publicación.
Para ejecutar una aplicación de .NET Core en Elastic Beanstalk, puede ejecutar dotnet publish y empaquetar la salida en un archivo ZIP, sin incluir los directorios que contiene. Coloque el archivo del sitio en un paquete de código fuente con un manifiesto de implementación que tenga un destino de implementación de tipo aspNetCoreWeb.
El siguiente manifiesto de implementación ejecuta una aplicación de .NET Core desde un archivo del sitio llamado dotnet-core-app.zip situado en la ruta raíz.
ejemplo aws-windows-deployment-manifest.json: .NET core
{
"manifestVersion": 1,
"deployments": {
"aspNetCoreWeb": [
{
"name": "my-dotnet-core-app",
"parameters": {
"archive": "dotnet-core-app.zip",
"iisPath": "/"
}
}
]
}
}Empaquete el manifiesto y el archivo del sitio en un ZIP para crear un paquete de código fuente.
ejemplo dotnet-core-bundle.zip
.
|-- aws-windows-deployment-manifest.json
`-- dotnet-core-app.zip
El archivo del sitio contiene el código compilado de la aplicación, las dependencias y el archivo web.config.
ejemplo 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.configEjecutar múltiples aplicaciones
Para ejecutar varias aplicaciones con un manifiesto de implementación, debe definir diferentes objetivos de implementación.
El manifiesto de implementación siguiente configura dos aplicaciones .NET Core. La aplicación WebApiSampleApp implementa una API web simple y sirve solicitudes asíncronas en la ruta /api. La aplicación DotNetSampleApp es una aplicación web que atiende solicitudes en la ruta raíz.
ejemplo aws-windows-deployment-manifest.json: varias aplicaciones
{
"manifestVersion": 1,
"deployments": {
"aspNetCoreWeb": [
{
"name": "WebAPISample",
"parameters": {
"appBundle": "WebApiSampleApp.zip",
"iisPath": "/api"
}
},
{
"name": "DotNetSample",
"parameters": {
"appBundle": "DotNetSampleApp.zip",
"iisPath": "/"
}
}
]
}
}Aquí hay disponible una aplicación de muestra con varias aplicaciones:
-
Paquete de código fuente implementable: dotnet-multiapp-sample-bundle-v2.zip
-
Código fuente: dotnet-multiapp-sample-source-v2.zip
Configurar sitios web de IIS
Puede configurar sitios web de IIS con enlaces personalizados y rutas físicas mediante el manifiesto de implementación. Esto resulta útil cuando necesita configurar sitios web que escuchen en puertos específicos, usen nombres de host personalizados o publiquen contenido de directorios específicos.
El siguiente manifiesto de implementación configura un sitio web de IIS personalizado que escucha en HTTP con un número de puerto específico y una ruta física personalizada:
ejemplo aws-windows-deployment-manifest.json: configuración de un sitio web de 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": "/"
}
}
]
}
}En este ejemplo:
-
Se crea un sitio web denominado MyCustomSite "» con una ruta física personalizada
-
El sitio web tiene un enlace HTTP en el puerto 8080 con un nombre de host específico.
-
La aplicación ASP.NET principal se implementa en este sitio web personalizado mediante el
iisWebSiteparámetro
Uso de enrutamiento de solicitudes de aplicaciones (ARR)
Los módulos de enrutamiento de solicitudes de aplicaciones (ARR) y de reescritura de URL vienen preinstalados y disponibles en las AMI de Windows de Elastic Beanstalk. Estos módulos permiten escenarios de enrutamiento avanzados y la manipulación de URL mediante la configuración de IIS con configuración de ebextensions o aplicaciones.
El siguiente ejemplo muestra un manifiesto de implementación simple que configura un sitio web con un puerto personalizado, combinado con una configuración de ebextensions que establece el enrutamiento de ARR básico:
ejemplo aws-windows-deployment-manifest.json: configuración simple de 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"
}
}
]
}
}La configuración de ARR se realiza a través de ebextensions. La siguiente configuración establece las reglas básicas de enrutamiento de ARR:
ejemplo. ebextensions/arr-config.config: configuración básica de 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: 0Esta configuración crea un sitio web en el puerto 8080 y configura ARR para enrutar todas las solicitudes entrantes a la aplicación de backend que se ejecuta en ese sitio.
Configuración de grupos de aplicaciones
Puede admitir varias aplicaciones en su entorno Windows. Hay dos enfoques disponibles:
-
Puede utilizar el modelo de alojamiento fuera de proceso con el servidor web Kestrel. Con este modelo, puede configurar varias aplicaciones para que se ejecuten en un grupo de aplicaciones.
-
Puede utilizar el modelo de alojamiento en proceso. Con este modelo, se utilizan varios grupos de aplicaciones para ejecutar varias aplicaciones con solo una aplicación en cada grupo. Si utiliza el servidor IIS y necesita ejecutar varias aplicaciones, debe utilizar este enfoque.
Si desea configurar Kestrel para que ejecute varias aplicaciones en un grupo de aplicaciones, agregue hostingModel="OutofProcess" en el archivo web.config. Considere los siguientes ejemplos:
ejemplo web.config: para el modelo de alojamiento fuera de proceso de 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>ejemplo aws-windows-deployment-manifest.json: para varias aplicaciones
{
"manifestVersion": 1,
"deployments": {"msDeploy": [
{"name": "Web-app1",
"parameters": {"archive": "site1.zip",
"iisPath": "/"
}
},
{"name": "Web-app2",
"parameters": {"archive": "site2.zip",
"iisPath": "/app2"
}
}
]
}
}IIS no admite varias aplicaciones en un grupo de aplicaciones porque utiliza el modelo de alojamiento en proceso. Por lo tanto, debe configurar varias aplicaciones mediante la asignación de cada aplicación a un grupo de aplicaciones. En otras palabras, asigne solo una aplicación a un grupo de aplicaciones.
Puede configurar IIS para que use diferentes grupos de aplicaciones en el archivo aws-windows-deployment-manifest.json. Realice las siguientes actualizaciones al consultar el siguiente archivo de ejemplo:
-
Agregue una sección
iisConfigque incluya una subsección llamadaappPools. -
En el bloque
appPools, enumere los grupos de aplicaciones. -
En la sección
deployments, defina una secciónparameterspara cada aplicación. -
Para cada aplicación, la sección
parametersespecifica un archivo, una ruta de acceso para ejecutarlo y unaappPoolen la que se ejecutará.
El siguiente manifiesto de implementación configura dos grupos de aplicaciones que reinician su aplicación cada 10 minutos. También adjuntan sus aplicaciones a una aplicación web .NET Framework que se ejecuta en la ruta especificada.
ejemplo aws-windows-deployment-manifest.json: una aplicación por grupo de aplicaciones
{
"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 implementaciones personalizadas
Para tener aún más control, puede personalizar completamente la implementación de una aplicación y definir una implementación personalizada. Con una implementación personalizada, Elastic Beanstalk ejecuta solo los PowerShell scripts que usted proporciona; no realiza ninguna administración de IIS en su nombre. Esto difiere de aspNetCoreWeb las implementaciones, en msDeploy las que Elastic Beanstalk detiene automáticamente IIS antes de instalarlo, lo inicia después y lo reinicia cuando es necesario. Para una implementación personalizada, los scripts colocan el contenido de la aplicación, configuran el entorno (por ejemplo, IIS) y reinician la aplicación.
importante
En un entorno de servidor web con equilibrio de carga, Elastic Beanstalk comprueba el estado de las instancias solicitando la ruta de verificación del estado del entorno (de forma / predeterminada) en el puerto 80. Debe haber algo que sirva para esa ruta o, de lo contrario, el entorno deja de funcionar correctamente aunque todos los scripts de implementación se ejecuten correctamente, lo que suele provocar que una implementación personalizada se complete sin errores, pero que deje el entorno en estado rojo. Para realizar una implementación personalizada e independiente, publique la aplicación desde la raíz del sitio web predeterminado. Es válido colocar una aplicación personalizada en una subruta cuando otra implementación ya utiliza la ruta de verificación de estado, por ejemplo, en un manifiesto de varias aplicaciones. Ejecutar múltiples aplicaciones Para obtener más información sobre el estado del entorno, consulte Monitorización de entornos. Monitoreo de entornos en Elastic Beanstalk
Una implementación personalizada define hasta tres scripts. En la siguiente tabla se describe cada script, cuándo lo ejecuta Elastic Beanstalk y qué debe hacer el script.
| Script | Cuando lo ejecuta Elastic Beanstalk | Responsabilidad |
|---|---|---|
uninstall |
Antes de instalar cada nueva versión de la aplicación, es decir, antes del despliegue de cada aplicación. | Detenga el servicio o elimine los archivos de la versión anterior. |
install |
Durante el despliegue de cada aplicación. | Implemente archivos, configure IIS o su servicio y entregue la aplicación en la ruta de verificación de estado. |
restart |
Después de cada implementación de la aplicación y después de cada cambio de configuración. Si se establece skipIISReset entrue, Elastic Beanstalk omite este script en las implementaciones de aplicaciones, pero lo sigue ejecutando en los cambios de configuración. Al seleccionar Restart App Server, se ejecuta a nivel de plataforma iisreset y no se invoca el script de reinicio personalizado. |
Reinicie IIS (iisreset) o su servicio para que la nueva versión esté disponible. |
Estos scripts también se ejecutan cada vez que Elastic Beanstalk implementa la aplicación en una instancia recién lanzada (por ejemplo, durante la creación inicial del entorno y cuando Auto Scaling agrega una instancia (escalamiento horizontal), porque cada instancia nueva instala la aplicación a medida que se inicia.
El siguiente manifiesto de implementación indica a Elastic Beanstalk que ejecute los scripts en modo de 32 bits. PowerShell Especifica un install script (install.ps1), un restart script () y un script (restart.ps1). uninstall uninstall.ps1 El uninstall script se establece ignoreErrors para true que la primera implementación, cuando no haya nada que eliminar, no falle.
ejemplo aws-windows-deployment-manifest.json: implementación 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
}
}
}
]
}
}Incluya los artefactos necesarios para ejecutar la aplicación en el paquete de código fuente con el manifiesto y los scripts. Elastic Beanstalk no extrae estos artefactos para una implementación personalizada; sus scripts deben extraerlos. En el siguiente ejemplo, el contenido de la aplicación se empaqueta como. MyApp.zip
ejemplo Custom-site-bundle.zip
.
|-- aws-windows-deployment-manifest.json
|-- install.ps1
|-- restart.ps1
|-- uninstall.ps1
`-- MyApp.zip
Los siguientes scripts muestran una implementación personalizada completa y correcta de una IIS-hosted aplicación. El install.ps1 script extrae el contenido de la aplicación y señala hacia él la ruta física del sitio web predeterminado, de modo que la aplicación se envía desde la ruta raíz (/) donde se realiza la comprobación de estado.
ejemplo install.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 }ejemplo reiniciar.ps1
$ErrorActionPreference = "Stop"
iisreset.exe /restart
if ($LASTEXITCODE -ne 0) { exit 1 }ejemplo 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 SilentlyContinueTenga en cuenta los siguientes puntos al escribir scripts de implementación personalizados:
-
Indique la ruta de verificación de estado. Dirija la ruta física del sitio web predeterminado a su aplicación o, de lo contrario, impleméntela en la ruta de verificación de estado para que la verificación de estado se realice correctamente.
-
Incluya un documento predeterminado. Si la raíz del sitio no tiene ningún documento predeterminado,
GET /devuelve HTTP 403 y se produce un error en la comprobación de estado. Envíe unweb.configarchivo que establezca un<defaultDocument>elemento o asigne a la página de destino un nombre que coincida con el nombre de un documento predeterminado de IIS, comoDefault.htmoindex.htm. -
Reinicie IIS usted mismo. Como Elastic Beanstalk no realiza ninguna administración de IIS para las implementaciones personalizadas, los scripts deben ejecutarse para que los cambios
iisresetsurtan efecto. -
Busque los archivos empaquetados en relación con el script. Elastic Beanstalk extrae los scripts y los artefactos agrupados en el mismo directorio. Resuelva los archivos empaquetados comparándolos con
$PSScriptRoot(la carpeta que contiene el script en ejecución) en lugar de asumir un directorio de trabajo actual en particular. -
Haga que los errores impidan la implementación. Configure
$ErrorActionPreference = "Stop"y compruebe$LASTEXITCODEdespués de los comandos externos. De lo contrario, un script dañado puede cerrarse correctamente y Elastic Beanstalk considera que la implementación se ha realizado correctamente aunque la aplicación no se ejecute correctamente.
Ejemplo: un servicio de Windows autohospedado
Con una implementación personalizada, puede ejecutar un servicio de Windows en lugar de un IIS-hosted sitio. Las plataformas Windows de Elastic Beanstalk no admiten el nivel de entorno de trabajo. En un entorno con equilibrio de carga, el balanceador de cargas comprueba la ruta de verificación de estado en el puerto 80, por lo que un servicio de Windows debe responder a esa solicitud para mantener el entorno en buen estado. El siguiente ejemplo es un servicio autohospedado que escucha en el propio puerto 80, por lo que no necesita un sitio de IIS complementario.
nota
Como las plataformas Windows no tienen un nivel de trabajo, un servicio que solo funciona en segundo plano debe responder a la comprobación de estado en un entorno de carga equilibrada. Haga que el servicio también responda a la ruta de verificación de estado (como se muestra aquí) o ejecute el trabajo en segundo plano junto con un sitio que lo publique.
El manifiesto ejecuta los scripts en modo de 64 bits, de manera que coincide con el compilador de C# de 64 bits utilizado para crear el servicio.
ejemplo aws-windows-deployment-manifest.json: servicio de Windows
{
"manifestVersion": 1,
"deployments": {
"custom": [
{
"name": "EbCustomService",
"architecture": 64,
"scripts": {
"install": {
"file": "serviceInstall.ps1"
},
"restart": {
"file": "serviceRestart.ps1"
},
"uninstall": {
"file": "serviceUninstall.ps1",
"ignoreErrors": true
}
}
}
]
}
}El paquete incluye el manifiesto, los tres scripts, el código fuente del servicio y un version.txt archivo (cuyo contenido es la cadena de versión, por ejemplo). v1 El script de instalación compila el servicio en la instancia, por lo que no necesitas incluir una cadena de herramientas de compilación en tu paquete.
ejemplo Custom-service-bundle.zip
.
|-- aws-windows-deployment-manifest.json
|-- EbCustomService.cs
|-- serviceInstall.ps1
|-- serviceRestart.ps1
|-- serviceUninstall.ps1
`-- version.txtEl serviceInstall.ps1 script libera el puerto 80 de IIS, compila el servicio a partir del código fuente incluido con el compilador de C# (csc.exe) incorporado, lo registra como servicio y lo inicia. LocalSystem Al ejecutar as, el LocalSystem servicio se enlaza http://+:80/ sin una reserva de URL y ACL, lo que reduce al mínimo el ejemplo. En producción, prefiera una cuenta con privilegios mínimos, por ejemplo, NetworkService y concédale el enlace de forma explícita con. netsh http add urlacl
ejemplo servicio 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 $svcNameEl serviceRestart.ps1 script reinicia el servicio para que la nueva versión esté disponible.
ejemplo servicio Restart.ps1
# RESTART: restart the service so the new version becomes live.
$ErrorActionPreference = "Stop"
$svcName = "EbCustomService"
Restart-Service $svcName -ForceEl serviceUninstall.ps1 script detiene y elimina el servicio y elimina los archivos de la versión anterior. El manifiesto se establece ignoreErrors en este script porque la primera implementación no tiene ninguna versión anterior que eliminar. true
ejemplo servicio 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
}El servicio en sí es un pequeño programa de C# que aloja un HttpListener activado http://+:80/ y devuelve una respuesta de texto paraGET /, que es lo que satisface la comprobación del estado del balanceador de cargas.
ejemplo 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
En este ejemplo, la respuesta que aparece / es un pequeño marcador de texto (marker.txt) que representa el contenido real de la aplicación. En su lugar, un servicio de producción proporcionaría sus propias respuestas. El resto de estos scripts es el mínimo necesario para que la implementación personalizada de un servicio de Windows funcione correctamente.