Cómo construir una plataforma de libro electrónico y no morir en el intento

2,481 views

Published on

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,481
On SlideShare
0
From Embeds
0
Number of Embeds
556
Actions
Shares
0
Downloads
21
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Cómo construir una plataforma de libro electrónico y no morir en el intento

  1. 1. CÓMO  CONSTRUIR  UNA  PLATAFORMA  DE  LIBRO   ELECTRÓNICO   Y   NO  MORIR   EN  EL  INTENTO  
  2. 2. Los speakersAlberto  Vilches   Roberto  Mar=n      •  Programando  desde  1998   •  Programador  desde  2008  •  5  años  de  experiencia  con  Grails   •  4  años  de  experiencia  con  Grails  •  Soy  el  que  organiza  todo  esto   •  Miembro  de  plataforma  Java  en  BQ  •  TwiIer:  @albertovilches   •  TwiIer:  @roberto_mf  
  3. 3. De que vamos a hablar10%  Negocio    20%  Experiencia    30%  Arquitectura    40%  Grails  (con  algo  de  código!)    
  4. 4. Donde trabajamos
  5. 5. Donde trabajamosMundoreader  –  BQ  Readers    •  Empresa  100%  española  (sedes  en  todo  el  mundo)  •  2º  fabricante  y  vendedor  de  tablets  en  España   (después  de  Apple)  •  Primera  plataforma  completa  de  libro  electrónico.  •  Y  otros  negocios:  memorias  USB,  accesorios,  etc.  
  6. 6. NegocioNegocio  principal:  venta  de  disposiNvos   (tablets,  ereaders)     Beneficios   €   Inversión  Siguiente  objebvo:  venta  de  contenidos  
  7. 7. NegocioVenta  de  contenido   •  Diseño,  creación  y   distribución  de  E-­‐readers   •  Acuerdos  con  editoriales   •  Creación  de  plataforma  de   venta  de  libros  
  8. 8. Modelo de negocio1.  BQReaders  NO  es  una  benda  de  libros  2.  Los  libros  los  venden  las  Nendas   grandes  librerías  y  superficies  /  pequeños  comercios   no  podemos  decir  quienes…    3.  Lo  hacen  a  través  de  nuestra  plataforma  4.  Y  nos  llevamos  comisión  por  libro  vendido  -­‐>                    !!!  5.  ¿Tienes  una  benda?  ¿Eres  una  editorial?  Habla  con   nosotros!    
  9. 9. Modelo de negocio1.  Las  bendas  usan  nuestra  plataforma   para  crear  una  web  y  vender  libros    aunque  a  veces  se  la  hacemos  también  nosotros…                !    2.  Las  bendas  venden  E-­‐readers  a  sus  usuarios  3.  Lo  hacen  con  su  marca,  pero  nos  los  compran  a   nosotros…              !  4.  Vendemos  la  solución  completa  
  10. 10. Modelo de negocioY  más  cosas     1.  Suscripción   Esblo  Spobfy:  cuota  mensual  y  barra  libre     2.  Bibliotecas   Préstamos,  adquisición  de  licencias   3.  Aplicaciones  en  IOS  y  Android      
  11. 11. Cómo funcionaCompra  y  lee   Consumen     libros   Servicios  (muchos!)      Tienda  WEB       App  nabva  IOS   Plataforma   contenidos   App  nabva  Android   E-­‐Reader  
  12. 12. Plataforma de contenidosTecnologías  usadas  •  Grails   3  wars:  services,  content,  backoffice    •  MySql   2  esquemas  en  2  máquinas  disbntas   1.  SERVICES  (usuarios,  compras,  disposibvos)   2.  CONTENT  (libros,  editoriales,  categorías,  catálogos)  
  13. 13. Plataforma de contenidosTecnologías  usadas  •  ElasbcSearch   •  Búsqueda  de  libros,  facetas   •  Evita  acceder  a  la  base  de  datos     •  Si  se  cae,  usamos  la  base  de  datos  (pero  no  tenemos  facetas)  •  Mahout   •  Recomendaciones  de  libros  en  función  de  las  compras  y  visitas  •  MongoDB   •  Auditoría  y  tablas  maestras  (paises-­‐ips,  reports,  )  
  14. 14. Plataforma de contenidosComponentes  •  API  para  bendas:  JSON  100%  (rest  90%)    Listados  de  libros,  búsquedas,  categorías,  compras  •  API  para  Ereader,  IOS  y  Android    Sincronizar  librería,  descargar  libro,  anotaciones,  bookmarks  •  Carga  de  contenidos     Proceso  nocturno  desde  editoriales  (tp,  epubs,  pdf,  onix,  carátulas)  •  Backoffice   Administración  de  libros,  categorías,  catálogos,  reports,   liquidaciones  
  15. 15.   Problemas  y…     “nuestras”  soluciones    
  16. 16. Plataforma de contenidos API  En  caso  de  error:     •  Debe  seguir  devolviendo  JSON   •  Si  es  un  error  incontrolado,  debe  nobficar  del  error   •  Log,  auditoria,  email          
  17. 17. Plataforma de contenidos API    
  18. 18. Plataforma de contenidos API    
  19. 19. Plataforma de contenidos Seguridad  API    “No  queremos  usar  login/token/sesión  por  cliente”      
  20. 20. Plataforma de contenidos Seguridad  API    “No  queremos  usar  login/token/sesión  por  cliente”     1.  Las  password  son  siempre  débiles   2.  El  cliente  no  maneja  sesión   3.  El  servidor  tampoco  (stateless,  más  fácil  de   replicar)   Solución:  pebciones  firmadas    
  21. 21. Plataforma de contenidos Seguridad  API  Firmar  una  pebción     •  Se  concatena  la  url  y  todos  sus  parámetros  (get  o  post,   todos)   •  Se  obbene  su  hash   •  Se  encripta  la  hash  con  la  clave  privada  =  firma   •  Se  envía  la  firma  en  una  cabecera   hex(  crypt(  sha1(  url+params,  key  )  )  )   •  El  servidor  hace  el  paso  inverso.  Si  los  parámetros   coinciden,  ejecuta  la  operación.    
  22. 22. Plataforma de contenidos Seguridad  API     Al  estar  basada  en  una  hash,  la  firma  cambiará   cada  vez  que  cambie  la  url  y/o  los  parámetros.     Interceptar  la  firma  no  permite  manipular  la   pebción    ¡Pero  una  pebción  interceptada  se  puede  replicar  N   veces!  
  23. 23. Plataforma de contenidos Seguridad  API  Evitar  que  se  repliquen  las  pebciones    Solución:  nonce   •  Cada  pebción  debe  enviar  un  parámetro  obligatorio  llamado   “nonce”.   •  Su  valor  debe  ser  un  número  no  usado  antes  (milesegundos?)   •  El  servidor  conserva  cada  nonce  enviado  y  verifica  que  no  se   repita.   •  Si  se  envía  el  mismo  “nonce”  se  rechaza  la  pebción.  
  24. 24. Algunos trucosTrabajar  con  decimales    
  25. 25. Algunos trucosTrabajar  con  decimales  •  Los  números  decimales  pierden  precisión  cuando  se   transforman  de  binario  a  decimal  •  No  importa  cuando  trabajamos  con  muchos  decimales   (de  hecho,  es  necesario):  distancias,  pesos  •  Pero  SI  importa  cuando  trabajamos  con  precios!  
  26. 26. Algunos trucosTrabajar  con  decimales:  solución    1.  Clases  de  dominio:  usar  BigDecimal!
  27. 27. Algunos trucosTrabajar  con  decimales:  solución    1.  Clases  de  dominio:  usar  BigDecimal!2.  Base  de  datos.  Precisión  de  n+1  para   productos   3  decimales  para  €  -­‐>  DECIMAL(16,  3)  
  28. 28. Algunos trucosTrabajar  con  decimales:  solución    1.  Clases  de  dominio:  usar  BigDecimal!2.  Base  de  datos.  Precisión  de  n+1  para   productos   3  decimales  para  €  -­‐>  DECIMAL(16,  3)  3.  Base  de  datos.  Precisión  de  n  para  compras   2  decimales  para  €  -­‐>  DECIMAL(15,  2)  
  29. 29. Algunos trucosTrabajar  con  decimales:  solución    1.  Clases  de  dominio:  usar  BigDecimal!2.  Base  de  datos.  Precisión  de  n+1  para   productos   3  decimales  para  €  -­‐>  DECIMAL(16,  3)  3.  Base  de  datos.  Precisión  de  n  para  compras   2  decimales  para  €  -­‐>  DECIMAL(15,  2)  4.  Evitar  recalcular    Al  hacer  una  compra,  guardar  una  “foto”  con  todos  los  valores  ya  calculados.  
  30. 30. Concurrencia Típico  problema  de  concurrencia    
  31. 31. Concurrencia Típico  problema  de  concurrencia    1.  Un  usuario  se  conecta  desde  diferentes   clientes  a  la  vez  (ipad  y  web),…  2.  …  ejecuta  dos  operaciones  que  escriben  en   el  mismo  registro  de  la  base  de  datos…              
  32. 32. Concurrencia Típico  problema  de  concurrencia    
  33. 33. ConcurrenciaA)  Cuando  NO  ES  un  registro  importante:                Fecha  de  úlbma  conexión/sincronización/ actualización            Actualizar  una  anotación  de  un  libro            Datos  personales  del  usuario,…        
  34. 34. ConcurrenciaA)  Cuando  NO  ES  un  registro  importante:    1.  Desacbvar  opbmisbc  locking  2.  Acbvar  dynamicUpdate  (opcional)        
  35. 35. Concurrencia A)  Cuando  NO  ES  un  registro  importante:     1.  Desacbvar  opbmisbc  locking   2.  Acbvar  dynamicUpdate  (opcional)       UPDATE … WHERE ID = 2678 AND VERSION = 10!  UPDATE table SET campo_que_ha_cambiado WHERE ID = 2678!
  36. 36. ConcurrenciaDynamicUpdate  PITFALL!!  LLLLLLL     Si  se  modifica  un  campo  dentro  de     beforeInsert  /  beforeUpdate   ¡No  se  escribirá!  Bug?     Solución:   Usar  beforeValidate   Se  ejecuta  después  de  save(),  al  insertar  o  modificar  
  37. 37. ConcurrenciaB)  Cuando  ES  un  registro  importante                                  Modificar  el  saldo  de  un  usuario              Devolver  una  compra                    Consumir  un  cupón  prepago    
  38. 38. ConcurrenciaB)  Cuando  ES  un  registro  importante  1.  Iniciar  transacción      
  39. 39. ConcurrenciaB)  Cuando  ES  un  registro  importante  1.  Iniciar  transacción  2.  Bloquear  el  registro        
  40. 40. ConcurrenciaB)  Cuando  ES  un  registro  importante  1.  Iniciar  transacción  2.  Bloquear  el  registro     SELECT * FROM USER … FOR UPDATE!    
  41. 41. Algunos trucosOperaciones  en  background  Escritura  de  logs,  actualizar  estadísbcas,  envío  de  mensajes,  colas…    
  42. 42. Algunos trucosOperaciones  en  background  Escritura  de  logs,  actualizar  estadísbcas,  envío  de  mensajes,  colas…    1.  Objebvo    Finalizar  la  pebción  lo  antes  posible  2.  Que  necesitamos:    Crear  un  hilo  con  la  sesión  de  Hibernate  3.  Plugins:   1.  BackgroundThread  plugin   2.  Executor   3.  Quartz    
  43. 43. Algunos trucosActualizaciones  masivas                  Si  hay  muchos  registros  (cientes  de  miles  o  millones)  •  Extremadamento  lento  •  Puedo  agotar  el  heap  •  No  es  eficiente  
  44. 44. Algunos trucosActualizaciones  masivas        •  A  veces  se  puede  susbtuir…  J    
  45. 45. Algunos trucosActualizaciones  masivas    •  Pero  otras  no  se  puede!           Cada  registro  requiere  lógica  de  negocio  L  
  46. 46. Algunos trucosActualizaciones  masivas    Solución   •  Hilo  en  background   •  Seleccionar  solo  lo  necesario  (projecbons)   •  Paginar  (hacer  de  1000  en  1000  elementos)   •  Limpiar  la  sesión  de  nivel  de  1  de  Hibernate   •  Introducir  pausas  si  es  necesario  Si  falla  todo  lo  demás   •  Crear  un  PLSQL  y  llamarlo  on  demand  o  por  la  noche  
  47. 47. Algunos trucosActualizaciones  masivas    
  48. 48. Algunos trucosActualizaciones  masivas     Projection
  49. 49. Algunos trucosActualizaciones  masivas     Paginación
  50. 50. Algunos trucosActualizaciones  masivas     Pausa Vaciar la sesión de Hibernate
  51. 51. Algunos trucosActualizaciones  masivas     ¿Que  sucede  si  cada  operación  individual   es  muuuuuy  lenta?     Cada  operación  una  llamada  a  un   servicio  externo…    
  52. 52. Algunos trucosActualizaciones  masivas     ¿Que  sucede  si  cada  operación  individual   es  muuuuuy  lenta?    SOLUCIÓN:  Un  pool  de  hilos    
  53. 53. Algunos trucosActualizaciones  masivas  Configuración  pool  de  hilos:  plugin  Executor        
  54. 54. Algunos trucosActualizaciones  masivas  Configuración  pool  de  hilos:  plugin  Executor   Número de hilos máximos a la vez      
  55. 55. Algunos trucosActualizaciones  masivas   Se obtienen primero SOLO los ids        
  56. 56. Algunos trucosActualizaciones  masivas     Se encola la operación   Operación lenta: Cargo € en tarjeta    
  57. 57. Algunos trucosActualizaciones  masivas     Se encola la operación   Operación lenta: Cargo € en tarjeta     Esperamos a que acaben todos los hilos
  58. 58. Algunos trucosActualizaciones  masivas           Vaciamos la sesión de Hibernate y volvemos a empezar
  59. 59. Escalabilidad        
  60. 60. EscalabilidadArquitectura   Tiendas  (web)     hIps://services.mundoreader.com       Tomcat  Grails   hIps://panel.mundoreader.com   MySql  
  61. 61. EscalabilidadArquitectura   Tiendas  (web)     hIps://services.mundoreader.com   Stateless!!  JJJJ       Tomcat  Grails   hIps://panel.mundoreader.com   MySql  
  62. 62. EscalabilidadArquitectura   Tiendas  (web)     hIps://services.mundoreader.com   Stateless!!  JJJJ       Tomcat  Grails   hIps://panel.mundoreader.com  
  63. 63. EscalabilidadArquitectura   Tiendas  (web)     hIps://services.mundoreader.com   Stateless!!  JJJJ       Tomcat  Grails   hIps://panel.mundoreader.com  
  64. 64. EscalabilidadEvitar  trabajo  innecesario  -­‐>  Delegar  en  la  bbdd.    Evitar  N+1  consultas.  Peligro!  Gorm!!     •  Usar  JOINs.  Crear  índices  si  es  necesario.   •  Inyectar  propiedades  (valores  agrupados,  etc)   •  Desnormalizar    
  65. 65. EscalabilidadInyectar  propiedades   •  En  vez  de:      
  66. 66. EscalabilidadInyectar  propiedades   •  En  vez  de:   •  Usar    
  67. 67. EscalabilidadAnalizar  el  rendimiento  de  la  bbdd   •  OpenNMS   •  Script  de  análisis   •  MySql  Slow  Queries   show variables like slow_query_log;! set global slow_query_log=ON;! ! /var/log/mysql/mysql-slow.log! !
  68. 68. EscalabilidadArquitectura     hIps://services.mundoreader.com   Stateless!!  JJJJ       Tomcat  Grails   hIps://panel.mundoreader.com  
  69. 69. EscalabilidadDividir  el  esquema  en  dos  •  2  MySql  fisicamente  disbntas  •  Relaciones  ligeras  entre  tablas  de  disbnta  bbdd  •  2  datasources  por  Tomcat  •  No  JOINs!  -­‐>  Desnormalizar   Tomcat  Grails   hIps://panel.mundoreader.com       MySql  MySql   1   2  
  70. 70. EscalabilidadEscalabilidad  Dos  datasources  •  Configuración  •  Clases  de  dominio        
  71. 71. EscalabilidadRendimiento  DESNORMALIZAR  •  Duplicar  datos  de  otras  tablas  •  Evita  joins  -­‐>  más  rápido  •  Perdida  de  consistencia  •  Uso  de  otros  bpos  de  base  de  datos   •  Libros  -­‐>  ElasbcSearch   •  Auditoría  -­‐>  MongoDb  con  Gorm      
  72. 72. EscalabilidadRendimiento  ElasbcSearch    •  Motor  de  búsqueda  en  texto  plano  •  Basado  en  Lucene  •  Api  JSON  100%  •  Alta  escalabilidad:  cluster,  nodos,  shards  •  Facetas      
  73. 73. EscalabilidadRendimiento  ElasbcSearch  Problema:  Indexar  desde  diferentes  puntos  de  la  aplicación    •  Al  modificar  un  libro  •  Al  modificar  una  categoría  (actualizar  todos  sus   libros)  •  Al  modificar  un  catálogo                    “                                “                “              “  •  Bucles,  hilos  de  fondo,  barras  de  progreso…  LLL    
  74. 74. EscalabilidadRendimiento  ElasbcSearch  Problema:  Indexar  desde  diferentes  puntos  de  la  aplicación  Solución:  Demonio  de  indexación     •  Único  punto  de  acceso  al  ES  para  escribir   •  Conbnuamente  procesa  libros  encolados  para   indexar   •  Para  indexar  un  libro,  solo  hay  que  encolarlo      
  75. 75. EscalabilidadRendimiento  ElasbcSearch  Problema:  Indexar  desde  diferentes  puntos  de  la  aplicación  Solución:  Demonio  de  indexación     •  Al  arrancar,  si  no  hay  nodo,  lo  crea  y  reindexa   •  Permite  encolar  reindexaciones  completas   •  Reconstruir  con  alias  (truco)   •  Índice  por  versión  de  app.      
  76. 76. EscalabilidadRendimiento  Cachear  todo!!   •  SpringCache   •  JCS   •  Implementaciones  propias  MySql   •  Cluster  Master/Slave   •  Servidores  read  only   •  Amazon  RDS  
  77. 77. EscalabilidadRendimiento  Pruebas  de  carga:  conoce  tu  límite   •  Antes  y  después  de  aplicar  mejoras.  Mide  lo  que  has   ganado.  Profile  tus  JVMs   •  YourKit  Java  Profiler:  memory  leaks,  threads   •  Java  Melody  (no  funciona  con  múlbples  datasources)   •  Plugin  BigDesk  para  ElasbcSearch  
  78. 78. MonitorizaciónCrea  tu  propia  página  de  información  
  79. 79. MonitorizaciónMonitorizar:  página  con  información  
  80. 80. MonitorizaciónCrea  tu  propia  página  de  información  
  81. 81. MonitorizaciónCrea  tu  propia  página  de  información    <app>/scripts/_Events.groovy!
  82. 82. MonitorizaciónCrea  tu  propia  página  de  información    1.  Mostrar  estado  de   servicios  2.  Chequeo  de   servicios  3.  Mostrar  hosts/ips      
  83. 83. MonitorizaciónCrea  tu  propia  página  de  información    1.  Mostrar  estado  de   servicios  2.  Chequeo  de   servicios  3.  Mostrar  hosts/ips      
  84. 84. MonitorizaciónCrea  tu  propia  página  de  información    1.  Mostrar  estado  de   servicios  2.  Chequeo  de   servicios  3.  Mostrar  hosts/ips      
  85. 85. Pase a producciónBuild  •  Scripts  de  update  SVN,  war  y  upload  a  repo  Test  •  SoapUI  y  manuales  Config  •  Configuración  externa  en  SVN  y  por  versión  Deploy  •  Script  de  descarga  de  war  desde  repo  (por  versión)  Rollback  •  Dump  de  base  datos.  Deploy  versión  anterior.  Config   se  conserva  entre  versiones.    
  86. 86. Pase a producciónConfig          Un  directorio  por  versión:          
  87. 87.         ¡Gracias!       ¿Preguntas?  (Tienen  premio!)  

×