Três anos de Scala em Produção:
desafios, aprendizados e dores de
cabeça
Felipe Hummel
Onilton Maciel
• Site profissional de monitoramento de notícias
• Coletando diariamente +30K sites
• 140M de notícias
• 5M/mês
• +20 máqui...
Como começamos em
Scala?
• 2010/2011
• Scala 2.7 => Scala 2.8
• Início na Spix em Janeiro de
2012
• busk.com
• Código lega...
Como começamos em
Scala?
• Movemos a Busca para o
ElasticSearch usando Scala.
• Resolvemos contornar o
código Ruby (nada c...
Busk => NewsMonitor
• busk.com foi fechado e
pivotamos para o
NewsMonitor (profissional)
• Decisão de reaproveitar
código l...
Busk => NewsMonitor
• busk.com foi fechado e
pivotamos para o
NewsMonitor (profissional)
• Decisão de reaproveitar
código l...
CrawlerSlaveCrawlerSlave
Elastic
Search
Elastic
Search
MySQL
Arquitetura
FeedCrawler
SiteCrawler
CrawlerSlave
Stark
(proce...
Arquitetura
Stark
(processamento)
Indexer
SearchAPI
autocomplete
SocialCrawler
CrawlerSlaveCrawlerSlave
FeedCrawler
SiteCr...
Scala: 2.7 ao 2.12
• 2.9 Maio/2011 <— NewsMonitor
• 2.10 - Janeiro/2013
• String interpolation, value classes, scala.concu...
Scala: 2.7 ao 2.12
• 2.11 - Abril/2014
• Poucas novas features (case class > 22)
• Pouca pressão para fazer upgrade
• Maio...
Scala: 2.7 ao 2.12
• Retro-compatibilidade melhorou bastante
• Linguagem vai mais devagar agora
• Libs que param no tempo ...
Deploy e Ops
• Simples (mas automatizado)
• SSH
• git pull
• sbt compile (sbt start-script)
• sudo restart crawler
• Deplo...
SBT
• Simple Build Tool?
• Sintaxe um pouco esotérica
• Nunca tivemos muitos problemas
• Usamos apenas build.sbt
• Um proj...
Compilador
• Compilação é lenta
• Compilação incremental (sbt ~compile) resolve na maior
parte do tempo
• Mudar algo impor...
Estilo de Scala
• Muitas formas de escrever o mesmo código
• Um mais cool, outro mais funcional, outro mais
imperativo
• Q...
Estilo de Scala
Estilo de Scala
<— Usamos
<— Usamos
<— Usamos
<— Usamos
<— Usamos
Estilo de Scala
Estilo de Scala
Estilo de Scala
• Empolgação é nossa inimiga
• Typeclasses são legais mas não precisamos criar uma implementação
própria p...
Dicas
• Cuidado com default parameter
• Dois parâmetros do mesmo tipo com default
• Adicionar parâmetro com default e esqu...
Estilo de Scala
• ScalaStyle (https://github.com/scalastyle/scalastyle)
• Scapegoat (https://github.com/sksamuel/scalac-sc...
Estilo de Scala
• scalacOptions += “-deprecation"
• scalacOptions += “-unchecked” (unchecked type-args)
• scalacOptions +=...
Akka
• Framework para concorrência baseada (principalmente)
em Actors
• Actors são objetos "especiais"
• Você não chama um...
Akka
Akka e NewsMonitor
• Nossos Crawlers são 100% Akka
• Começamos no Akka 2.0
• 2.0 tinha coisas pouco desenvolvidas
• Como u...
Akka :)
• Simplifica muito o modelo mental para trabalhar com concorrência
• Cria "bolhas" onde você pode ser mutável à von...
Akka :(
• Toma conta do código (framework)
• A relação entre actors não é tão óbvia no código quanto a relação entre objet...
Akka Dicas
• Não criar Actor pra executar código trivial achando que vai ser mais eficiente
• Actors tem overhead
• É comum...
Quando Usar Akka
• Quando o problema é inerentemente concorrente/paralelo
• Crawler é um bom exemplo
• Actors de vida long...
Outras libs
• Scalatra: usamos em todas APIs
• Similar ao Sinatra (Ruby)
• Mais simples quase impossível
• Funciona muito ...
Conclusões
• Programação funcional é o futuro
• Options >>> null
• Case classes: parece pouco mas mudam a forma de program...
Dúvidas?
felipe.hummel@newsmonitor.com.br
Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça
Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça
Próximos SlideShares
Carregando em…5
×

Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça

227 visualizações

Publicada em

Como o NewsMonitor começou a usar Scala, além de Akka e Scalatra, no início de 2012 e os desafios e problemas que encontramos.

Publicada em: Tecnologia
0 comentários
2 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

Sem downloads
Visualizações
Visualizações totais
227
No SlideShare
0
A partir de incorporações
0
Número de incorporações
3
Ações
Compartilhamentos
0
Downloads
2
Comentários
0
Gostaram
2
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça

  1. 1. Três anos de Scala em Produção: desafios, aprendizados e dores de cabeça Felipe Hummel Onilton Maciel
  2. 2. • Site profissional de monitoramento de notícias • Coletando diariamente +30K sites • 140M de notícias • 5M/mês • +20 máquinas no EC2 • 2 Devs Backend + 3 Devs PHP/Frontend/Aplicação • 3 anos com Scala em produção • 30K linhas de código Scala
  3. 3. Como começamos em Scala? • 2010/2011 • Scala 2.7 => Scala 2.8 • Início na Spix em Janeiro de 2012 • busk.com • Código legado em Ruby • Ninguém viu, ninguém sabia • Código feito por “consultoria" • O que fazer?
  4. 4. Como começamos em Scala? • Movemos a Busca para o ElasticSearch usando Scala. • Resolvemos contornar o código Ruby (nada contra) • ElasticSearch pega direto do BD ao invés de conversar com o Coletor de noticias • Coletor de Feed RSS deixava notícias passarem (intervalo de coleta fixo gerava atrasos) • Começamos a implementar o nosso coletor em Scala + Akka
  5. 5. Busk => NewsMonitor • busk.com foi fechado e pivotamos para o NewsMonitor (profissional) • Decisão de reaproveitar código legado em Ruby ou criar novo • Em Scala? Ruby? Python?
 

  6. 6. Busk => NewsMonitor • busk.com foi fechado e pivotamos para o NewsMonitor (profissional) • Decisão de reaproveitar código legado em Ruby ou criar novo • Em Scala? Ruby? Python? • Escolhemos PHP • Por boas razões no momento
  7. 7. CrawlerSlaveCrawlerSlave Elastic Search Elastic Search MySQL Arquitetura FeedCrawler SiteCrawler CrawlerSlave Stark (processamento) Indexer MySQL Redis SearchAPI Elastic Search
  8. 8. Arquitetura Stark (processamento) Indexer SearchAPI autocomplete SocialCrawler CrawlerSlaveCrawlerSlave FeedCrawler SiteCrawler CrawlerSlave MySQLMySQL Redis Elastic Search Elastic Search Elastic Search
  9. 9. Scala: 2.7 ao 2.12 • 2.9 Maio/2011 <— NewsMonitor • 2.10 - Janeiro/2013 • String interpolation, value classes, scala.concurrent • Pressão da comunidade para fazer upgrade • Muitas libs exigindo 2.10 (macros, macros, macros!) • Começamos a migrar em agosto de 2013. Mas 100% 2.10 só em agosto de 2014.
  10. 10. Scala: 2.7 ao 2.12 • 2.11 - Abril/2014 • Poucas novas features (case class > 22) • Pouca pressão para fazer upgrade • Maioria das libs cross-compilando 2.10/2.11 • Retro-compatibilidade bem melhor que 2.9 => 2.10 • 2.12 - Janeiro/2016 ??? • Java 8 only. • Melhor performance de lambdas? • @interface traits • Vamos de 2.10 => 2.12?
  11. 11. Scala: 2.7 ao 2.12 • Retro-compatibilidade melhorou bastante • Linguagem vai mais devagar agora • Libs que param no tempo ainda podem ser problema (cross-compila aí fazendo favor!) • Caso Querulous (https://github.com/twitter/querulous) • Ótimo wrapper do JDBC feito pelo Twitter • 3 anos sem commits (niver semana passada) • Oficialmente compilado só pra 2.9 • Vários forks com ports para 2.10 • Caso Goose (https://github.com/GravityLabs/goose) • Forks com PRs e compilação pra 2.10
  12. 12. Deploy e Ops • Simples (mas automatizado) • SSH • git pull • sbt compile (sbt start-script) • sudo restart crawler • Deploys elásticos • Gerar AIM/docker/algo ou gerar fat-jar (sbt-assembly) • Hoje, geramos AIMs mas queremos mudar pra fat-jar.
  13. 13. SBT • Simple Build Tool? • Sintaxe um pouco esotérica • Nunca tivemos muitos problemas • Usamos apenas build.sbt • Um projeto por repositório. Sem multi-projects • Dica: sempre especificar versão do SBT no project/ build.properties • Sempre: sbt ~compile OU sbt ~test OU sbt “~test-only …”
  14. 14. Compilador • Compilação é lenta • Compilação incremental (sbt ~compile) resolve na maior parte do tempo • Mudar algo importante do projeto gera uma compilação lenta • Crawler com 9.1K linhas • sbt clean compile => 1min 27segs • Projetos maiores devem sofrer mais
  15. 15. Estilo de Scala • Muitas formas de escrever o mesmo código • Um mais cool, outro mais funcional, outro mais imperativo • Qual usar?
  16. 16. Estilo de Scala
  17. 17. Estilo de Scala <— Usamos <— Usamos <— Usamos <— Usamos <— Usamos
  18. 18. Estilo de Scala
  19. 19. Estilo de Scala
  20. 20. Estilo de Scala • Empolgação é nossa inimiga • Typeclasses são legais mas não precisamos criar uma implementação própria pra serialização, pra JSON, pra concorrência, pra…. • Implicits são legais mas toda função ter implicit é NÃO • UrlFetcher no Crawler funcionou muito bem • Macros são legais. Nunca chegamos a criar novos • Implicit conversions são legais mas podem gerar código aparentemente mágico • Se usar, é bom limitar o escopo onde é utilizado • Densidade de código
  21. 21. Dicas • Cuidado com default parameter • Dois parâmetros do mesmo tipo com default • Adicionar parâmetro com default e esquecer de mudar os lugares que precisavam passar • null não kct! Option sempre • Toda equipe tentar seguir o mesmo padrão • Code review ajuda a manter estilo
  22. 22. Estilo de Scala • ScalaStyle (https://github.com/scalastyle/scalastyle) • Scapegoat (https://github.com/sksamuel/scalac-scapegoat- plugin) • Wart remover (https://github.com/typelevel/wartremover) • Linter (https://github.com/HairyFotr/linter) • CPD (https://github.com/sbt/cpd4sbt) • Abide (https://github.com/scala/scala-abide) • Caminhando pra ser “O" oficial agora
  23. 23. Estilo de Scala • scalacOptions += “-deprecation" • scalacOptions += “-unchecked” (unchecked type-args) • scalacOptions += “-feature” (reclama de features avançadas) • scalacOptions += “-Xlint" (faz checagens de boas práticas) • Tem gente que usa: scalacOptions += "-Xfatal- warnings"
  24. 24. Akka • Framework para concorrência baseada (principalmente) em Actors • Actors são objetos "especiais" • Você não chama um método de um Actor de fora dele • Você manda uma mensagem (objetos imutáveis) para ele e em algum momento no futuro ele vai processar • Qualquer código dentro de um Actor é garantido que só vai rodar em condições thread-safe
  25. 25. Akka
  26. 26. Akka e NewsMonitor • Nossos Crawlers são 100% Akka • Começamos no Akka 2.0 • 2.0 tinha coisas pouco desenvolvidas • Como usar? Melhores práticas? Boas arquitetura? • Remoting. Actors em máquinas diferentes • Meu conhecimento de Akka • Hoje: Akka 2.3 • Muito mais maduro • Akka Cluster
  27. 27. Akka :) • Simplifica muito o modelo mental para trabalhar com concorrência • Cria "bolhas" onde você pode ser mutável à vontade (com moderação) • Muito bom quando você tem Actors de vida longa e com estado mutável • Não precisa lidar com criação/manutenção de filas (na maior parte do tempo) • Tunar threadpools (dispatchers) não é necessário no início e é bem fácil (via config) • O código do Actor não contém (quase) nada de lógica lidando com concorrência, threads ou threadpool
  28. 28. Akka :( • Toma conta do código (framework) • A relação entre actors não é tão óbvia no código quanto a relação entre objetos num código tradicional (perca de tipagem) • Você pode acabar tunando ExecutionContexts e ThreadPool de qualquer forma. E não é trivial (independente do Akka). • Mais "difícil" de testar • Dá pra isolar algumas coisas e criar determinismo • No final das contas tudo é concorrente • Debugar é bem diferente • Rastrear de onde uma coisa veio, pra onde vai…
  29. 29. Akka Dicas • Não criar Actor pra executar código trivial achando que vai ser mais eficiente • Actors tem overhead • É comum precisar de pelo menos um Dispatcher específico pra IO • Bulkhead: separar Dispatchers por uso para evitar starvation e garantir responsividade • Evita que o problema de uma área atrapalhe outras • eventually {} nos testes • O isolamento de actors não é desculpa pra usar coisas mutáveis por toda parte • vars não são proibidas dentro de um Actor mas é possível evitar • Toda estrutura de dados deve ser "owned" por um Actor • Pode ser mutável, contanto que não vaze para fora do Actor
  30. 30. Quando Usar Akka • Quando o problema é inerentemente concorrente/paralelo • Crawler é um bom exemplo • Actors de vida longa e com estado mutável • Não tão necessário se tudo o que precisa é rodar uns jobs em background. • Dá pra ir longe com: ExecutionContexts + Future • Mais simples de entender (e mais familiar para boa parte dos devs) • Casos mais simples e tradicionais de "Processamento de Request" (APIs/ RPCs em geral) podem ser resolvidos com Futures • Twitter
  31. 31. Outras libs • Scalatra: usamos em todas APIs • Similar ao Sinatra (Ruby) • Mais simples quase impossível • Funciona muito bem para APIs • ScalaTest • Metrics (https://github.com/dropwizard/metrics) • HTTP • Dispatch (http://dispatch.databinder.net/). DSL curiosa • WS (acoplado ao Play)
  32. 32. Conclusões • Programação funcional é o futuro • Options >>> null • Case classes: parece pouco mas mudam a forma de programar • Muito fácil se aproveitar das bibliotecas já existentes em Java • IDE: Sublime/Eclipse/IntelliJ • Como somos uma equipe minúscula (2), não encontramos vários problemas • Escolhas se estivéssemos começando hoje • Scala + SBT de certeza • Scalatra para APIs simples. Play para uma aplicação completa (NewsMonitor) • Querulous nunca mais. Slick? ScalikeJDBC? • Akka no Crawler de certeza. Com Akka Cluster talvez não usaria fila externa
  33. 33. Dúvidas?
  34. 34. felipe.hummel@newsmonitor.com.br

×