가동 중지 시간없이 ASP.NET 응용 프로그램을 배포하는 방법
새 버전의 웹 사이트를 배포하려면 다음을 수행하십시오.
- 새 코드를 압축하여 서버에 업로드하십시오.
- 라이브 서버의 IIS 웹 사이트 디렉토리에서 모든 라이브 코드를 삭제하십시오.
- 비어있는 IIS 디렉토리에 새 코드 zip 파일을 추출하십시오.
이 프로세스는 모두 스크립팅되며 매우 빠르게 수행되지만 이전 파일을 삭제하고 새 파일을 배포 할 때 여전히 10-20 초의 다운 타임이있을 수 있습니다.
0 초의 다운 타임 방법에 대한 제안이 있으십니까?
2 대의 서버와로드 밸런서가 필요합니다. 단계는 다음과 같습니다.
- 서버 2에서 모든 트래픽 설정
- 서버 1에 배포
- 테스트 서버 1
- 서버 1의 모든 트래픽을 켭니다.
- 서버 2에 배포
- 테스트 서버 2
- 두 서버 모두에서 트래픽 전환
이 경우에도 "고정 세션"을 사용하는 경우에도 응용 프로그램이 다시 시작되고 세션이 손실됩니다. 데이터베이스 세션이나 상태 서버가 있으면 모든 것이 정상입니다.
마이크로 소프트 웹 배포 도구는 어느 정도이 지원 :
Windows 트랜잭션 파일 시스템 (TxF) 지원을 사용합니다. TxF 지원이 활성화되면 파일 작업이 원 자성입니다. 즉, 그들은 성공하거나 완전히 실패합니다. 이렇게하면 데이터 무결성이 보장되고 "반쯤"또는 손상된 상태로 데이터 또는 파일이 존재하지 않습니다. MS Deploy에서 TxF는 기본적으로 비활성화되어 있습니다.
트랜잭션이 전체 동기화를위한 것 같습니다. 또한 TxF는 Windows Server 2008의 기능이므로이 트랜잭션 기능은 이전 버전에서는 작동하지 않습니다.
폴더를 버전 및 IIS 메타베이스로 사용하여 0 다운 타임에 대한 스크립트를 수정할 수 있다고 생각합니다.
- 기존 경로 / URL의 경우 :
- 경로 : \ web \ app \ v2.0 \
- url : http : // app
- 새 (또는 수정 된) 웹 사이트를 아래 서버로 복사
- \ 웹 \ 앱 \ v2.1 \
- 웹 사이트 경로를 변경하도록 IIS 메타베이스 수정
- 에서 \ 웹 \ 응용 프로그램 \ 2.0 \
- 에 \ 웹 \ 응용 프로그램 \ 2.1 \
이 방법은 다음과 같은 이점을 제공합니다.
- 새 버전에 문제가있는 경우 v2.0으로 쉽게 롤백 할 수 있습니다
- 여러 실제 또는 가상 서버에 배포하기 위해 파일 배포에 스크립트를 사용할 수 있습니다. 모든 서버에 새 버전이 설치되면 Microsoft 웹 배포 도구를 사용하여 모든 서버의 메타베이스를 동시에 변경할 수 있습니다.
다른 포트의 두 로컬 IIS 사이트간에 소프트웨어로드 밸런서로 IIS의 응용 프로그램 요청 라우팅을 사용하여 단일 서버에서 중단없는 배포를 달성 할 수 있습니다. 이를 로드 밸런서에서 언제든지 두 사이트 중 하나만 사용할 수있는 청록색 배포 전략 이라고합니다. "다운 된"사이트에 배포하고 워밍업 한 다음로드 밸런서 (일반적으로 Application Request Routing 상태 확인을 통과하여)로 가져간 다음 "풀"에서 원래 사이트를 가져옵니다 (다시) 상태 확인 실패).
나는 이것을 최근에 겪었고 내가 생각해 낸 해결책은 IIS에 두 개의 사이트를 설정하고 그들 사이를 전환하는 것이 었습니다.
내 구성을 위해 다음과 같이 각 A 및 B 사이트에 대한 웹 디렉토리가 있습니다. c : \ Intranet \ Live A \ Interface c : \ Intranet \ Live B \ Interface
IIS에는 각각 자체 응용 프로그램 풀이있는 두 개의 동일한 사이트 (같은 포트, 인증 등)가 있습니다. 사이트 중 하나가 실행 중이고 (A) 다른 사이트가 중지되었습니다 (B). 라이브 하나에는 라이브 호스트 헤더도 있습니다.
라이브로 배포 할 때는 STOPPED 사이트 위치에 게시하기 만하면됩니다. 포트를 사용하여 B 사이트에 액세스 할 수 있기 때문에 첫 번째 사용자가 응용 프로그램을 시작하지 않도록 사이트를 미리 예열 할 수 있습니다. 그런 다음 배치 파일을 사용하여 라이브 호스트 헤더를 B에 복사하고 A를 중지 한 다음 B를 시작합니다.
Microsoft.Web.Administration의 ServerManager 클래스를 사용하면 자체 배포 에이전트를 개발할 수 있습니다.
비법은 VirtualDirectory의 PhysicalPath를 변경하여 기존 웹 응용 프로그램과 새 웹 응용 프로그램간에 온라인 원자 전환을 수행하는 것입니다.
이로 인해 이전 및 새 AppDomain이 병렬로 실행될 수 있습니다!
문제는 데이터베이스 변경 사항을 동기화하는 방법입니다.
이전 또는 새로운 PhysicalPaths를 사용하여 AppDomain의 존재를 폴링하면 이전 AppDomain이 종료 된 시점과 새 AppDomain이 시작되었는지 여부를 감지 할 수 있습니다.
AppDomain을 강제로 시작하려면 HTTP 요청을해야합니다 (IIS 7.5는 자동 시작 기능을 지원합니다)
이제 새 AppDomain에 대한 요청을 차단할 방법이 필요합니다. 이름이 지정된 mutex (배포 에이전트가 작성 및 소유하고 새 웹 앱의 Application_Start에서 대기 한 후 데이터베이스 업데이트가 완료되면 배치 에이전트에 의해 릴리스 됨)를 사용합니다.
(I use a marker file in the web app to enable the mutex wait behaviour) Once the new web app is running I delete the marker file.
OK so since everyone is downvoting the answer I wrote way back in 2008*...
I will tell you how we do it now in 2014. We no longer use Web Sites because we are using ASP.NET MVC now.
We certainly do not need a load balancer and two servers to do it, that's fine if you have 3 servers for every website you maintain but it's total overkill for most websites.
Also, we don't rely on the latest wizard from Microsoft - too slow, and too much hidden magic, and too prone to changing its name.
Here's how we do it:
We have a post build step that copies generated DLLs into a 'bin-pub' folder.
We use Beyond Compare (which is excellent**) to verify and sync changed files (over FTP because that is widely supported) up to the production server
We have a secure URL on the website containing a button which copies everything in 'bin-pub' to 'bin' (taking a backup first to enable quick rollback). At this point the app restarts itself. Then our ORM checks if there are any tables or columns that need to be added and creates them.
That is only milliseconds downtime. The app restart can take a second or two but during the restart requests are buffered so there is effectively zero downtime.
The whole deployment process takes anywhere from 5 seconds to 30 minutes, depending how many files are changed and how many changes to review.
This way you do not have to copy an entire website to a different directory but just the bin folder. You also have complete control over the process and know exactly what is changing.
**We always do a quick eyeball of the changes we are deploying - as a last minute double check, so we know what to test and if anything breaks we ready. We use Beyond Compare because it lets you easily diff files over FTP. I would never do this without BC, you have no idea what you are overwriting.
*Scroll to the bottom to see it :( BTW I would no longer recommend Web Sites because they are slower to build and can crash badly with half compiled temp files. We used them in the past because they allowed more agile file-by-file deployment. Very quick to fix a minor issue and you can see exactly what you are deploying (if using Beyond Compare of course - otherwise forget it).
The only zero downtime methods I can think of involve hosting on at least 2 servers.
I would refine George's answer a bit, as follows, for a single server:
- Use a Web Deployment Project to pre-compile the site into a single DLL
- Zip up the new site, and upload it to the server
- Unzip it to a new folder located in a folder with the right permissions for the site, so the unzipped files inherit the permissions correctly (perhaps e:\web, with subfolders v20090901, v20090916, etc)
- Use IIS Manager to change the name of folder containing the site
- Keep the old folder around for a while, so you can fallback to it in the event of problems
Step 4 will cause the IIS worker process to recycle.
This is only zero downtime if you're not using InProc sessions; use SQL mode instead if you can (even better, avoid session state entirely).
Of course, it's a little more involved when there are multiple servers and/or database changes....
To expand on sklivvz's answer, which relied on having some kind of load balancer (or just a standby copy on the same server)
- Direct all traffic to Site/Server 2
- Optionally wait a bit, to ensure that as few users as possible have pending workflows on the deployed version
- Deploy to Site/Server 1 and warm it up as much as possible
- Execute database migrations transactionally (strive to make this possible)
- Immediately direct all traffic to Site/Server 1
- Deploy to Site/Server 2
- Direct traffic to both sites/servers
It is possible to introduce a bit of smoke testing, by creating a database snapshot/copy, but that's not always feasible.
If possible and needed use "routing differences", such as different tenant URL:s (customerX.myapp.net) or different users, to deploy to an unknowing group of guinea pigs first. If nothing fails, release to everyone.
Since database migrations are involved, rolling back to a previous version is often impossible.
There are ways to make applications play nicer in these scenarios, such as using event queues and playback mechanisms, but since we're talking about deploying changes to something that is in use, there's really no fool proof way.
This is how I do it:
Absolute minimum system requirements:
1 server with
- 1 load balancer/reverse proxy (e.g. nginx) running on port 80
- 2 ASP.NET-Core/mono reverse-proxy/fastcgi chroot-jails or docker-containers listening on 2 different TCP ports
(or even just two reverse-proxy applications on 2 different TCP ports without any sandbox)
Workflow:
start transaction myupdate
try
Web-Service: Tell all applications on all web-servers to go into primary read-only mode
Application switch to primary read-only mode, and responds
Web sockets begin notifying all clients
Wait for all applications to respond
wait (custom short interval)
Web-Service: Tell all applications on all web-servers to go into secondary read-only mode
Application switch to secondary read-only mode (data-entry fuse)
Updatedb - secondary read-only mode (switches database to read-only)
Web-Service: Create backup of database
Web-Service: Restore backup to new database
Web-Service: Update new database with new schema
Deploy new application to apt-repository
(for windows, you will have to write your own custom deployment web-service)
ssh into every machine in array_of_new_webapps
run apt-get update
then either
apt-get dist-upgrade
OR
apt-get install <packagename>
OR
apt-get install --only-upgrade <packagename>
depending on what you need
-- This deploys the new application to all new chroots (or servers/VMs)
Test: Test new application under test.domain.xxx
-- everything that fails should throw an exception here
commit myupdate;
Web-Service: Tell all applications to send web-socket request to reload the pages to all clients at time x (+/- random number)
@client: notify of reload and that this causes loss of unsafed data, with option to abort
@ time x: Switch load balancer from array_of_old_webapps to array_of_new_webapps
Decomission/Recycle array_of_old_webapps, etc.
catch
rollback myupdate
switch to read-write mode
Web-Service: Tell all applications to send web-socket request to unblock read-only mode
end try
I would suggest keeping the old files there and simply overwriting them. That way the downtime is limited to single-file overwrite times and there is only ever one file missing at a time.
Not sure this helps in a "web application" though (i think you are saying that's what you're using), which is why we always use "web sites". Also with "web sites" deploying doesn't restart your site and drop all the user sessions.
참고URL : https://stackoverflow.com/questions/148084/how-to-deploy-an-asp-net-application-with-zero-downtime
'Programming' 카테고리의 다른 글
PHP ORM : 교리와 프로 펠 (0) | 2020.07.06 |
---|---|
Firebase를 사용하여 이름 속성별로 사용자 확보 (0) | 2020.07.06 |
Mercurial에서 닫힌 지점을 다시 열 수 있습니까? (0) | 2020.07.06 |
얕은 자식 서브 모듈을 만드는 방법? (0) | 2020.07.06 |
Python, 유니 코드 및 Windows 콘솔 (0) | 2020.07.06 |