330 lines
10 KiB
Markdown
330 lines
10 KiB
Markdown
---
|
|
title: "Migração ASP 3.0 para .NET Core - Sistema de Rastreamento de Cargas"
|
|
slug: "asp-to-dotnet-migration"
|
|
summary: "Tech Lead na migração gradual de sistema crítico ASP 3.0 para .NET Core, com sincronização de dados entre versões e redução de custos de R$ 100k/ano em APIs de mapeamento."
|
|
client: "Empresa de Logística e Rastreamento"
|
|
industry: "Logística & Segurança"
|
|
timeline: "12 meses (migração completa)"
|
|
role: "Tech Lead & Solution Architect"
|
|
image: ""
|
|
tags:
|
|
- ASP Classic
|
|
- .NET Core
|
|
- SQL Server
|
|
- Migration
|
|
- Tech Lead
|
|
- OSRM
|
|
- APIs
|
|
- Arquitetura
|
|
featured: true
|
|
order: 2
|
|
date: 2015-06-01
|
|
seo_title: "Migração ASP 3.0 para .NET Core - Case Carneiro Tech"
|
|
seo_description: "Case de migração gradual de aplicação ASP 3.0 para .NET Core com sincronização de dados e redução de R$ 100k/ano em custos de APIs."
|
|
seo_keywords: "ASP migration, .NET Core, legacy modernization, SQL Server, OSRM, tech lead, routing API"
|
|
---
|
|
|
|
## Overview
|
|
|
|
Sistema crítico de monitoramento de cargas de alto valor (TVs LED de R$ 3.000 cada, carregamentos de até 1000 unidades) usando rastreamento GPS via satélite. A aplicação cobria todo o ciclo: desde cadastro e avaliação de motoristas (background check policial) até monitoramento em tempo real e entrega final.
|
|
|
|
**Desafio principal:** Migrar aplicação ASP 3.0 legada para .NET Core sem downtime, mantendo operação crítica 24/7.
|
|
|
|
---
|
|
|
|
## Challenge
|
|
|
|
### Sistema Legado Crítico
|
|
|
|
A empresa operava um sistema mission-critical em **ASP 3.0** (Classic ASP) que não podia parar:
|
|
|
|
**Tecnologia legada:**
|
|
- ASP 3.0 (tecnologia de 1998)
|
|
- SQL Server 2005
|
|
- Cluster failover on-premises (perfeitamente capaz de suportar a carga)
|
|
- Integração com rastreadores GPS via satélite
|
|
- Google Maps API (custo: **R$ 100.000/ano** apenas para cálculo de rotas)
|
|
|
|
**Restrições:**
|
|
- Sistema operando 24/7 com cargas de alto valor
|
|
- Impossibilidade de downtime durante migração
|
|
- Múltiplos módulos interdependentes
|
|
- Equipe precisava continuar desenvolvendo features durante a migração
|
|
|
|
---
|
|
|
|
## Solution Architecture
|
|
|
|
### Fase 1: Preparação da Infraestrutura (Meses 1-3)
|
|
|
|
#### Upgrade do Banco de Dados
|
|
```
|
|
SQL Server 2005 → SQL Server 2014
|
|
- Backup completo e validação
|
|
- Migração de stored procedures
|
|
- Otimização de índices
|
|
- Testes de performance
|
|
```
|
|
|
|
#### Estratégia de Sincronização Dual-Write
|
|
|
|
Implementei um **sistema de sincronização bidirecional** que permitia:
|
|
|
|
1. **Módulos novos (.NET Core)** gravavam no banco novo
|
|
2. **Trigger automático** sincronizava dados para o banco legado
|
|
3. **Módulos antigos (ASP 3.0)** continuavam funcionando normalmente
|
|
4. **Zero downtime** durante toda a migração
|
|
|
|
```csharp
|
|
// Exemplo de sincronização implementada
|
|
public class DualWriteService
|
|
{
|
|
public async Task SaveDriver(Driver driver)
|
|
{
|
|
// Grava no banco novo (.NET Core)
|
|
await _newDbContext.Drivers.AddAsync(driver);
|
|
await _newDbContext.SaveChangesAsync();
|
|
|
|
// Trigger SQL sincroniza automaticamente para banco legado
|
|
// Módulos ASP 3.0 continuam funcionando
|
|
}
|
|
}
|
|
```
|
|
|
|
**Por que essa abordagem?**
|
|
- Permitiu migração **módulo por módulo**
|
|
- Equipe podia continuar desenvolvendo
|
|
- Rollback simples se necessário
|
|
- Redução de risco operacional
|
|
|
|
---
|
|
|
|
### Fase 2: Migração Gradual dos Módulos (Meses 4-12)
|
|
|
|
Migrei os módulos em ordem de complexidade crescente:
|
|
|
|
**Ordem de migração:**
|
|
1. ✅ Cadastros básicos (motoristas, veículos)
|
|
2. ✅ Avaliação de risco (integração com base policial)
|
|
3. ✅ Gestão de cargas e rotas
|
|
4. ✅ Monitoramento GPS em tempo real
|
|
5. ✅ Alertas e notificações
|
|
6. ✅ Relatórios e analytics
|
|
|
|
**Stack da aplicação migrada:**
|
|
- `.NET Core 1.0` (2015-2016 era o início do .NET Core)
|
|
- `Entity Framework Core`
|
|
- `SignalR` para monitoramento real-time
|
|
- `SQL Server 2014`
|
|
- APIs RESTful
|
|
|
|
---
|
|
|
|
### Fase 3: Redução de Custos com OSRM (Economia de R$ 100k/ano)
|
|
|
|
#### Problema: Custo Proibitivo do Google Maps
|
|
|
|
A empresa gastava **R$ 100.000/ano** apenas com Google Maps Directions API para cálculo de rotas dos caminhões.
|
|
|
|
#### Solução: OSRM (Open Source Routing Machine)
|
|
|
|
Implementei uma solução baseada em **OSRM** (motor de roteamento open-source):
|
|
|
|
**Arquitetura da solução:**
|
|
|
|
```
|
|
┌─────────────────┐
|
|
│ Frontend │
|
|
│ (Leaflet.js) │
|
|
└────────┬────────┘
|
|
│
|
|
▼
|
|
┌─────────────────┐ ┌──────────────┐
|
|
│ API Wrapper │─────▶│ OSRM Server │
|
|
│ (.NET Core) │ │ (self-hosted)│
|
|
└────────┬────────┘ └──────────────┘
|
|
│
|
|
▼
|
|
┌─────────────────┐
|
|
│ Google Maps │
|
|
│ (display only) │
|
|
└─────────────────┘
|
|
```
|
|
|
|
**Implementação:**
|
|
|
|
1. **OSRM Server configurado** em servidor próprio
|
|
2. **API wrapper amigável** em .NET Core que:
|
|
- Recebia origem/destino
|
|
- Consultava OSRM (gratuito)
|
|
- Retornava todos os pontos da rota
|
|
- Formatava para o frontend
|
|
3. **Frontend** desenhava a rota no Google Maps (apenas visualização, sem API de rotas)
|
|
|
|
```csharp
|
|
[HttpGet("route")]
|
|
public async Task<IActionResult> GetRoute(double originLat, double originLng,
|
|
double destLat, double destLng)
|
|
{
|
|
// Consulta OSRM (gratuito)
|
|
var osrmResponse = await _osrmClient.GetRouteAsync(
|
|
originLat, originLng, destLat, destLng);
|
|
|
|
// Retorna pontos formatados para o frontend
|
|
return Ok(new {
|
|
points = osrmResponse.Routes[0].Geometry.Coordinates,
|
|
distance = osrmResponse.Routes[0].Distance,
|
|
duration = osrmResponse.Routes[0].Duration
|
|
});
|
|
}
|
|
```
|
|
|
|
**Frontend com Leaflet:**
|
|
|
|
```javascript
|
|
// Desenha rota no mapa (Google Maps apenas para tiles)
|
|
L.polyline(routePoints, {color: 'red'}).addTo(map);
|
|
```
|
|
|
|
#### Tentativa com OpenStreetMap
|
|
|
|
Tentei substituir também o Google Maps (tiles) por **OpenStreetMap**, que funcionou tecnicamente, mas:
|
|
|
|
❌ **Usuários não gostaram** da aparência
|
|
❌ Preferiam a interface familiar do Google Maps
|
|
|
|
✅ **Decisão:** Manter Google Maps apenas para visualização (sem custo de API de rotas)
|
|
|
|
**Resultado:** Economia de **~R$ 100.000/ano** mantendo qualidade das rotas.
|
|
|
|
---
|
|
|
|
## Results & Impact
|
|
|
|
### Migração Completa em 12 Meses
|
|
|
|
✅ **100% dos módulos** migrados de ASP 3.0 para .NET Core
|
|
✅ **Zero downtime** durante toda a migração
|
|
✅ **Equipe produtiva** durante todo o processo
|
|
✅ Sistema mais rápido e escalável
|
|
|
|
### Redução de Custos
|
|
|
|
💰 **R$ 100.000/ano economizados** com substituição do Google Maps Directions API
|
|
📉 **Infraestrutura otimizada** com SQL Server 2014
|
|
|
|
### Melhorias Técnicas
|
|
|
|
🚀 **Performance:** Aplicação .NET Core 3x mais rápida que ASP 3.0
|
|
🔒 **Segurança:** Stack moderna com patches de segurança ativos
|
|
🛠️ **Manutenibilidade:** Código C# moderno vs VBScript legado
|
|
📊 **Monitoramento:** SignalR para tracking real-time mais eficiente
|
|
|
|
---
|
|
|
|
## Fase Não Executada: Microserviços & Cloud
|
|
|
|
### Planejamento Inicial
|
|
|
|
Participei do **design e concepção** da segunda fase (nunca executada):
|
|
|
|
**Arquitetura planejada:**
|
|
- Migração para **Azure** (cloud estava apenas começando em 2015)
|
|
- Quebra em **microserviços**:
|
|
- Serviço de autenticação
|
|
- Serviço de GPS/tracking
|
|
- Serviço de rotas
|
|
- Serviço de notificações
|
|
- **Event-driven architecture** com message queues
|
|
|
|
**Por que não foi executada:**
|
|
|
|
Saí da empresa logo após concluir a migração para .NET Core. A segunda fase ficou planejada mas não foi implementada por mim.
|
|
|
|
---
|
|
|
|
## Tech Stack
|
|
|
|
`ASP 3.0` `VBScript` `.NET Core 1.0` `C#` `Entity Framework Core` `SQL Server 2005` `SQL Server 2014` `OSRM` `Leaflet.js` `Google Maps` `SignalR` `REST APIs` `GPS/Satellite` `Migration Strategy` `Dual-Write Pattern`
|
|
|
|
---
|
|
|
|
## Key Decisions & Trade-offs
|
|
|
|
### Por que sincronização dual-write?
|
|
|
|
**Alternativas consideradas:**
|
|
1. ❌ Big Bang migration (muito arriscado)
|
|
2. ❌ Manter tudo em ASP 3.0 (insustentável)
|
|
3. ✅ **Migração gradual com sync** (escolhido)
|
|
|
|
**Justificativa:**
|
|
- Sistema crítico não podia parar
|
|
- Permitiu rollback módulo por módulo
|
|
- Equipe continuou produtiva
|
|
|
|
### Por que OSRM em vez de outros?
|
|
|
|
**Alternativas:**
|
|
- Google Maps: R$ 100k/ano ❌
|
|
- Mapbox: Licença paga ❌
|
|
- GraphHopper: Configuração complexa ❌
|
|
- **OSRM: Open-source, rápido, configurável** ✅
|
|
|
|
### Por que não OpenStreetMap para tiles?
|
|
|
|
**Decisão baseada em UX:**
|
|
- Tecnicamente funcionou perfeitamente
|
|
- Usuários preferiam interface familiar do Google
|
|
- **Compromisso:** Google Maps para visualização (grátis) + OSRM para rotas (grátis)
|
|
|
|
---
|
|
|
|
## Lessons Learned
|
|
|
|
### 1. Migração Gradual > Big Bang
|
|
|
|
Migrar módulo por módulo com sincronização permitiu:
|
|
- Aprendizado contínuo
|
|
- Ajustes de rota durante o processo
|
|
- Confiança da equipe e stakeholders
|
|
|
|
### 2. Open Source Pode Economizar Muito
|
|
|
|
OSRM economizou **R$ 100k/ano** sem perda de qualidade. Mas requer:
|
|
- Expertise para configurar
|
|
- Infraestrutura própria
|
|
- Manutenção contínua
|
|
|
|
### 3. UX > Tecnologia às Vezes
|
|
|
|
OpenStreetMap era tecnicamente superior (gratuito), mas usuários preferiram Google Maps. **Lição:** Ouvir os usuários finais.
|
|
|
|
### 4. Planeje Cloud, mas Valide o ROI
|
|
|
|
Em 2015, cloud estava começando. A infraestrutura on-premises (cluster SQL Server) era perfeitamente capaz. **Não force cloud se não há benefício claro.**
|
|
|
|
---
|
|
|
|
## Context: Por que 2015 foi um Momento Especial?
|
|
|
|
**Estado da tecnologia em 2015:**
|
|
|
|
- ☁️ **Cloud engatinhando:** AWS existia, Azure crescendo, mas adoção corporativa ainda baixa
|
|
- 🆕 **.NET Core 1.0 lançado** em junho/2016 (usamos RC durante projeto)
|
|
- 📱 **Microserviços:** Conceito novo, Docker em adoção inicial
|
|
- 🗺️ **Google Maps dominante:** APIs pagas, poucas alternativas open-source maduras
|
|
|
|
**Desafios da época:**
|
|
- Ferramentas de migração ASP→.NET inexistentes
|
|
- Documentação .NET Core escassa (versão 1.0!)
|
|
- Padrões de arquitetura ainda se consolidando
|
|
|
|
Este projeto foi **pioneiro** ao adotar .NET Core logo no início, quando a maioria migrava para .NET Framework 4.x.
|
|
|
|
---
|
|
|
|
**Resultado:** Migração bem-sucedida de sistema crítico 24/7, economia de R$ 100k/ano, e base sólida para evolução futura.
|
|
|
|
[Quer discutir uma migração similar? Entre em contato](#contact)
|