-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresumen.tex
1832 lines (1064 loc) · 141 KB
/
resumen.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}
\usepackage{indentfirst}
\usepackage{microtype}
\usepackage[hidelinks]{hyperref}
\title{Arquitectura de software [75.73] - Resumen Teórico}
\author{Franco Secchi}
\begin{document}
\maketitle
\renewcommand{\contentsname}{Contenidos}
\tableofcontents
\newpage
\section {Introducción a la arquitectura de software}
La arquitectura de software es un conjunto de \textbf{estructuras} fundamentales que permite razonar sobre un sistema, compuesto por \textbf{elementos} de software, sus \textbf{relaciones} y \textbf{propiedades}.
Cuando hablamos de \textbf{estructuras}, nos referimos a un conjunto de elementos unidos por relaciones. Los \textbf{elementos}, a su vez, se dividen en diferentes tipos, entre ellos:
\begin{enumerate}
\item \textbf{Módulos (Module)}: Los módulos son unidades de implementación a las que se les asignan responsabilidades específicas. Son una forma de dividir y organizar el código y las responsabilidades del software en partes más pequeñas y manejables, facilitando la modularización y el desarrollo del sistema.
\item \textbf{Componentes y controles (C\&C)}: El modelo arquitectónico C\&C se enfoca en dividir la responsabilidad de controlar y coordinar los componentes funcionales en un sistema de software. Los componentes del controlador toman decisiones y controlan el flujo del programa, mientras que los componentes de coordinación se encargan de la comunicación y sincronización entre otros componentes del sistema.
\end{enumerate}
Además de las estructuras mencionadas, también se considera la \textbf{Allocation} de componentes de software para componentes de hardware. El modelo de atribución se refiere a cómo se distribuye e implementa el software en el hardware disponible, lo que determina qué componentes, servidores o dispositivos del sistema se ejecutarán.
La separación entre módulos y componentes dinámicos, como se sugiere en el paradigma C\&C, permite un diseño arquitectónico independiente del tiempo de ejecución. Los módulos proporcionan vistas estructurales y estáticas del sistema, mientras que los componentes dinámicos representan la ejecución real del programa con todas sus versiones de tiempo de ejecución y comunicaciones.
\section{SLA}\label{sec:sla}
Un SLA, también conocido como Acuerdo de Nivel de Servicio (Service Level Agreement), es un contrato formal que establece los niveles de rendimiento y calidad que un proveedor de servicios se compromete a brindar a sus clientes. Un SLA establece las normas y expectativas en términos de disponibilidad, tiempo de respuesta, tiempo de resolución, calidad del servicio y otros factores importantes de rendimiento.
\section{Atributos de calidad y Tácticas}
Los atributos de calidad (también conocidos como requisitos no funcionales) son una \textbf{propiedad} \textit{mensurable o testeable del sistema} .
Los atributos de calidad son necesarios para evaluar y medir qué tan bien un sistema cumple con los estándares y expectativas del usuario, así como para garantizar que el software funcione de manera óptima y eficiente.
\subsection{Tácticas}
Una vez que comprendemos la importancia de los atributos de calidad, es natural querer maximizarlos todos en nuestro sistema. Sin embargo, nos enfrentamos al hecho de que no es posible satisfacer todos los atributos al mismo nivel. Por lo tanto, es imperativo tomar decisiones informadas sobre qué atributos de calidad se priorizan para el sistema y cómo equilibrarlos mediante el uso de tácticas adecuadas.
Las tácticas son técnicas o enfoques específicos que se utilizan para lograr atributos de calidad en la arquitectura de software. Cada atributo de calidad puede requerir tácticas específicas para mejorar o mantener su cumplimiento. Sin embargo, algunas tácticas pueden entrar en conflicto con otras o tener efectos secundarios no deseados en diferentes atributos de calidad.
Con este conflicto entramos en \textit{trade-off}, que se refiere a la necesidad de tomar decisiones que afectan a unos atributos en beneficio de otros.
\subsection{Availability \small{(Disponibilidad)}}
Es la habilidad del sistema para \textit{reparar} o \textit{enmascarar fallas} de manera tal que el período que el sistema está fuera de servicio no exceda un determinado valor durante un lapso de tiempo especificado.
Una falla (\textit{failure}) ocurre cuando el sistema deja de brindar un servicio consistente con su especificación.
Una falta (\textit{fault}) se convierte en falla si no es corregida o enmascarada.
\subsubsection{Tipos de fallas}
Los tipos de fallas que nos podemos encontrar son:
\begin{enumerate}
\item \textbf{Omission}: El sistema no responde a un pedido
\item \textbf{Crash}: El sistema sufre omisiones repetitivas.
\item \textbf{Timming}: El sistema responde, pero fuera de tiempo.
\item \textbf{Response Failure}: El sistema responde, pero con un valor incorrecto.
\end{enumerate}
\subsubsection{Regla de los cinco 9's}\label{sec:regla_nueves}
Es una métrica que se utiliza para medir la confiabilidad y disponibilidad de un sistema o servicio. Se expresa como un porcentaje y significa que el sistema está disponible el 99.999\% del tiempo.
Para calcular la disponibilidad en términos de "nueves", se considera el porcentaje de tiempo en el que el sistema está en funcionamiento en un año. Aquí está el desglose:
\begin{enumerate}
\item \textbf{Disponibilidad de 99\%}: El sistema está inactivo aproximadamente 3.65 días al año.
\item \textbf{Disponibilidad de 99.9\% (tres nueves)}: El sistema está inactivo aproximadamente 8.76 horas al año.
\item \textbf{Disponibilidad de 99.99\% (cuatro nueves)}: El sistema está inactivo aproximadamente 52.56 minutos al año.
\item \textbf{Disponibilidad de 99.999\% (cinco nueves)}: El sistema está inactivo aproximadamente 5.26 minutos al año.
\end{enumerate}
\subsubsection{Tácticas PDR}\label{sec:tacticas_disponibilidad}
Algunas técnicas PDR \footnote{El nombre PDR no es oficial, hice la abrevicación por comodidad. Es más, PDR es un nombre de una técnica para autos (Paintless Dent Repair)... Mira vos che. } (de prevención, detección y recuperación), en caso de que el atributo falle. que se pueden utilizar son:
\begin{itemize}
\item \textbf{Prevención}
\begin{enumerate}
\item \textbf{Diseño redundante}: La idea es implementar redundancia en componentes críticos para que, en caso de falla, otro componente pueda ocupar su lugar y mantener la disponibilidad del sistema.
\item \textbf{Transacciones}: El uso de transacciones en el diseño del sistema puede evitar incoherencias y la pérdida de datos en caso de error. Las transacciones garantizan que las operaciones se completen o reviertan por completo, manteniendo la integridad de los datos y asegurando la disponibilidad del sistema.
\end{enumerate}
\item \textbf{Detección}
\begin{enumerate}
\item \textbf{Envio de señales y monitoreo}: La idea es implementar mecanismos de detección que impliquen el envio de señales o mensajes periódicos entre componentes para verificar su estado y asegurar que sigan funcionando correctamente.
Un envio de señales puede ser el famoso \textit{Ping} y un sistema de monitoreo puede ser \textit{Datadog}.
\item \textbf{Votación}: Utilizado en sistemas con redundancia, la votación consiste en monitorear diferentes componentes y comparar sus resultados para detectar errores. Las coincidencias en la mayoría de los componentes se consideran válidas y las no coincidencias se ignoran, lo que permite detectar y recuperar las fallas del sistema.
\end{enumerate}
\item \textbf{Recuperación}
\begin{enumerate}
\item \textbf{Redundancia activa}: Esta táctica implica implementar componentes o servicios duplicados que se ejecutan simultáneamente, donde uno puede controlar y reanudar las operaciones en caso de que falle el componente principal. Esto permite una recuperación rápida y mejora la disponibilidad del sistema.
\item \textbf{Redundancia pasiva}: Similar a la redundancia activa, con la diferencia de que requiere una intervención manual para activar el componente redundante.
\item \textbf{Repuesto}: Esta táctica consiste en tener componentes de repuesto disponibles y listos para reemplazar rápidamente aquellos que fallen.
\end{enumerate}
\end{itemize}
\subsection{Performance \small{(Rendimiento)}}
Se refiere a la capacidad del sistema para responder a eventos y realizar sus funciones de manera rápida y eficiente.
Los eventos pueden ser de las siguientes naturalezas:
\begin{enumerate}
\item \textbf{Periódicos} (ej. cada 10 ms)
\item \textbf{Estocásticos} (ej. 100 req/s)
\item \textbf{Esporádicos} (ej. alarma)
\end{enumerate}
El rendimiento de un sistema se ve afectado por las interacciones entre sus elementos. Esto incluye la velocidad y la eficiencia en el uso de la red y la percepción del rendimiento por parte del usuario. La arquitectura del sistema juega un papel importante en la determinación de esta interacción.
La elección de una arquitectura adecuada es muy importante, ya que el rendimiento suele estar limitado por varios factores: los requisitos del sistema, en relación con la sobrecarga de procesamiento subyacente entre diferentes componentes; tipo de interacción seleccionado, que puede requerir múltiples interacciones para lograr resultados; arquitectura e implementación de cada componente, lo que puede afectar la velocidad a la que se generan o consumen los datos.
Una pregunta que nos podemos hacer es ¿cuándo atacar los problemas de performance? Bueno, es conveniente abordar los problemas de rendimiento en dos momentos clave:
\begin{enumerate}
\item \textbf{Durante el tiempo de ejecución}: En el caso de una aplicación en ejecución, puede resolver un problema de rendimiento proporcionando herramientas para que su código realice la acción correcta. Esto implica identificar áreas críticas donde el rendimiento puede verse afectado y recopilar datos sobre tiempos de respuesta, consumo de recursos y otras métricas relevantes. Con estas métricas en la mano, es posible optimizar el código y los algoritmos para mejorar la eficiencia y la velocidad de la aplicación.
\item \textbf{Optimizar de forma temprana}: Un enfoque proactivo es abordar el rendimiento temprano en el desarrollo, considerando todas las decisiones arquitectónicas. Al tomar decisiones de diseño, es importante considerar cómo estas opciones afectarán el rendimiento general del sistema. Algunas decisiones de arquitectura pueden ser difíciles de revertir o mejorar con la optimización tardía, por lo que es mejor abordarlas temprano para evitar problemas de rendimiento graves en el futuro.
\end{enumerate}
Es importante tener en cuenta que la optimización prematura no significa caer en la trampa de la optimización excesiva, lo que puede conducir a una arquitectura compleja que es difícil de mantener. En cambio, se trata de tomar decisiones informadas sobre el diseño del sistema que aseguren un buen rendimiento sin sacrificar la simplicidad y la claridad del código.
\subsubsection{Network Perfomance}
El rendimiento de la red es una variable importante para el funcionamiento óptimo del sistema. Este concepto se refiere al rendimiento y eficiencia con que la red de comunicación de un sistema transmite información entre sus componentes. Algunos de los aspectos clave a tener en cuenta al evaluar el rendimiento de la red son:
\begin{enumerate}
\item \textbf{Throughput}: Se define como la velocidad a la que se transfiere la información entre los diferentes componentes del sistema y, por lo general, se mide en bytes por segundo. Esta métrica incluye tanto los datos de la aplicación como los gastos generales asociados con la comunicación, que pueden surgir tanto de la configuración inicial como de la interacción de los componentes.
\item \textbf{Capacity}: Se refiere a la carga máxima que puede soportar, es decir, el rendimiento máximo que el sistema puede manejar de manera efectiva. Para medir la capacidad, las personas suelen utilizar el concepto de transacciones por segundo (tx/s, tps). Estas mediciones generalmente se realizan a través de pruebas de carga que utilizan transacciones representativas, como las más frecuentes o típicas, para evaluar si el sistema cumple con los requisitos establecidos.
\item \textbf{Bandwidth}\label{sec:bandwidth}: Representa el rendimiento máximo disponible en un canal de comunicación en particular. Esta es una medida importante para comprender la capacidad de transmisión de la red. Además, "ancho de banda utilizable" se refiere a la porción de ancho de banda disponible para la aplicación en cuestión que es relevante para determinar el rendimiento de la red en el contexto específico de la aplicación.
\item \textbf{Estilos de Interacción}: El estilo de la arquitectura juega un papel importante en la forma en que se comunican los componentes y, por lo tanto, afecta directamente el rendimiento de la red. Los estilos más efectivos buscan minimizar el acceso a la red, llegando incluso a evitar su uso en circunstancias apropiadas. Esto se logra mediante la reducción de la frecuencia de las interacciones y la reutilización de interacciones anteriores, lo que optimiza el rendimiento de la red.
\end{enumerate}
En resumidas palabras, el rendimiento de la red es fundamental para garantizar un funcionamiento eficiente del sistema y la capacidad de transferir información de manera eficiente entre sus componentes. Evaluar y optimizar el rendimiento, la capacidad, el ancho de banda y los patrones de interacción son pasos críticos para lograr un rendimiento óptimo de la red en el contexto de sistemas y aplicaciones complejos.
\subsubsection{User-Perceived Performance}
El nombre es bastante auto-explicativo, es una serie de métricas que evalúan el rendimiento de un sistema desde la perspectiva del usuario, teniendo en cuenta cómo perciben y experimentan el rendimiento del sistema en términos de tiempo de respuesta y eficiencia.
Hay 2 tipos de métricas:
\begin{enumerate}
\item \textbf{Completion Time (Response Time)}: Esta métrica representa el tiempo requerido por el sistema para completar una solicitud específica (request) desde la perspectiva del usuario. Dado que estos tiempos pueden ser pequeños, variables y dependientes de diferentes parámetros, su medición desde el exterior del sistema puede resultar desafiante.
\item \textbf{Latency}: Se refiere al tiempo mínimo que el sistema necesita para ejecutar cualquier solicitud, incluso si esta implica no realizar ninguna acción. Según la descripción de Fowler, es el tiempo que transcurre desde el estímulo inicial hasta la primera indicación de respuesta. Por otro lado, Fielding la define como el tiempo que pasa entre el estímulo inicial y la primera indicación de respuesta.
\end{enumerate}
Además, dentro de las mediciones de User-Perceived Performance, se encuentra el concepto de Responsiveness, que denota el tiempo que un sistema requiere para reconocer o "aceptar" una solicitud del usuario. Algunos ejemplos ilustran la importancia de esta métrica, como el caso de una progress bar que mejora la responsividad, pero no necesariamente afecta el completion time. Asimismo, comparando dos web browsers, uno que muestra una imagen grande a medida que la va recibiendo (mejorando la percepción de respuesta) y otro que no lo hace, se mantiene la misma Network Performance, pero la experiencia de usuario es mejor con una mayor User-Perceived Performance.
Es relevante señalar que optimizar la responsividad suele tener un impacto negativo en el completion time (y viceversa). Por ejemplo, al aumentar la tasa de compresión de la comunicación, se mejora la eficiencia conforme aumenta la cantidad de datos. Sin embargo, acumular datos antes de comprimirlos puede ayudar al completion time, pero a expensas de reducir la responsividad.
En muchas situaciones, es importante considerar cuidadosamente qué aspecto conviene priorizar, dependiendo del contexto y los usuarios involucrados. Por ejemplo, al optimizar el funcionamiento de un web-server, es necesario evaluar si del otro lado se encuentra un web browser (que prioriza una alta responsividad) o un web spider\footnote{Es un programa automatizado que recorre de manera sistemática y metódica la World Wide Web (léase Internet) para indexar información y recopilar datos de diferentes páginas web.} (que valora más el completion time). La comprensión de estas métricas y su impacto en la percepción del usuario es esencial para diseñar y mejorar sistemas que ofrezcan una experiencia óptima al usuario.
\subsubsection{Efficiency}
Es una medida importante que se refiere a la capacidad que tiene un sistema para ofrecer un rendimiento óptimo en relación con los recursos consumidos. Específicamente, la eficiencia se relaciona con la relación entre la performance y los recursos involucrados en cumplir con un pedido o en realizar una acción.
Es fundamental considerar que cada solicitud o actividad que el sistema realiza implica el uso de recursos, como el tiempo de ejecución, la memoria, la capacidad de almacenamiento, entre otros. En situaciones reales, es frecuente que el sistema esté manejando múltiples solicitudes al mismo tiempo, lo que implica el uso simultáneo y compartido de recursos.
Okey genial pero ¿como podemos \textbf{evaluar} la eficiencia? Fácil, con una prueba de \textbf{Load Test} o prueba de carga. Este tipo de pruebas simulan situaciones realistas de uso que nos permiten evaluar la eficiencia y la performance en diversas situaciones en las cuales se aumentan la carga.
El ultimo concepto importante sobre eficiencia es el \textit{Load Sensitivity} (\small{sensibilidad de carga, para los amigos}), este concepto representa la variación del tiempo de respuesta en función del nivel de carga. Cuando la performance empeora a medida que aumenta la carga, se evidencia una sensibilidad a la carga, lo cual indica que el sistema puede experimentar una disminución del rendimiento bajo cargas más altas.
\subsubsection{Tácticas}
Para la performance, las tácticas se dividen en dos categorías principales: \textbf{Control Resource Demand} y \textbf{Manage Resources}. Vamos a ver algunos ejemplos de cada uno:
\begin{itemize}
\item \textbf{Control Resource Demand}
\begin{enumerate}
\item \textbf{Cache}: Almacenar temporalmente resultados de operaciones costosas para evitar recálculos innecesarios. Esto reduce la carga de recursos como CPU, almacenamiento y red.
\item \textbf{Lazy Loading}: Cargar datos o recursos solo cuando se necesitan, en lugar de cargarlos todos al inicio. Esto disminuye la demanda inicial de recursos y optimiza el uso de memoria. Ejemplo: La carga de imágenes en una pagina. No se cargan todas de una, sino que las cargas cuando el usuario las tiene que ver.
\item \textbf{Prefetching}: Anticipar y cargar datos que probablemente serán requeridos en un futuro cercano, reduciendo así la latencia y mejorando la experiencia del usuario.
\item \textbf{Rate Limiting}: Restringir la cantidad de solicitudes que un usuario o sistema puede realizar en un período de tiempo determinado para evitar sobrecargas y mantener un rendimiento estable.
\end{enumerate}
\item \textbf{Manage Resources}
\begin{enumerate}
\item \textbf{Load Balancing}: Distribuir de manera equitativa las solicitudes entre varios servidores o recursos para evitar la sobrecarga en uno en particular y optimizar la utilización de recursos disponibles.
\item \textbf{Asynchronous Operations}: Utilizar operaciones asincrónicas para liberar recursos mientras se espera la finalización de ciertas tareas, permitiendo al sistema manejar más solicitudes concurrentes.
\item \textbf{Schedule Resources}: Es el acceso a recursos a traves de politicas como FIFO, prioridad fija, prioridad dinámica.
\end{enumerate}
\end{itemize}
\subsection{Scalability \small{(Escalabilidad)} }
Se refiere a su capacidad para soportar una gran cantidad de componentes o las interacciones entre ellos [Fielding]. Es la capacidad del sistema para adaptarse al aumento de usuarios, transacciones y niveles de actividad, entre otros factores.
La efectividad de agregar recursos al sistema es crucial para la escalabilidad. Esta efectividad se mide en términos de una mejora mensurable en una característica de calidad sin invertir recursos innecesarios o interrumpir el funcionamiento del sistema.
Hay dos métodos principales para lograr la escalabilidad:
\begin{enumerate}
\item \textbf{Escalabilidad vertical (scaling up)}: Es el proceso de agregar más recursos a las unidades físicas, lo que se conoce como "crecer en hardware". Por ejemplo, aumentar la memoria de un servidor. La mayoría de las veces, esta forma de escalabilidad requiere poco trabajo; sin embargo, hay límites en cuanto a la cantidad de recursos adicionales que se pueden agregar a una sola unidad.
\item \textbf{Escalabilidad horizontal (scaling out)}: implica agregar más recursos a las unidades lógicas, como tener múltiples servidores colaborando como un todo. El agregar más servidores a un clúster es un ejemplo de esto. Debido a la coordinación necesaria entre los servidores, esta forma de escalabilidad puede ser más potente, pero también puede ser más difícil de implementar.
\end{enumerate}
La elasticidad es un concepto relacionado que se refiere a la capacidad del sistema para aumentar o disminuir la cantidad de recursos en respuesta a los cambios en la demanda. Un ejemplo de este tipo de elasticidad es la escalabilidad horizontal en la nube, donde el sistema puede ajustar dinámicamente sus recursos para adaptarse a las fluctuaciones de carga.
\subsubsection{Tácticas}
\begin{itemize}
\item \textbf{Stateless}\label{sec:escalabilidad_tacticas}: implica diseñar los componentes del sistema de tal manera que no tengan información sobre el estado de las interacciones anteriores con el cliente. El tratamiento de cada solicitud del cliente se lleva a cabo de manera independiente, sin depender de ninguna información previamente almacenada. Esto facilita la escalabilidad horizontal porque se pueden agregar más instancias del componente sin preocuparse por el estado compartido.
\item \textbf{Horizontal Scale}: Es una estrategia para aumentar la capacidad del sistema agregando más instancias o nodos en paralelo. Para distribuir la carga, se agregan más componentes idénticos en lugar de aumentar los recursos de un solo componente. Es una buena manera de hacer frente al aumento de la demanda sin comprometer el rendimiento.
\item \textbf{Avoid Hardcoded Values}: Al evitar el uso de valores o configuraciones hardcodeados, se facilita la escalabilidad. Se recomienda utilizar configuraciones externas o parámetros fáciles de cambiar sin modificar el código fuente. Esto permite la modificación dinámica de elementos específicos del sistema sin necesidad de reconstruir o reiniciar el sistema en su conjunto.
\item \textbf{Async Design}: Permite que las tareas se realicen de manera no secuencial, evitando bloqueos y esperas innecesarias. Los patrones asíncronos permiten al sistema procesar solicitudes adicionales mientras se realizan otras tareas, lo que mejora la utilización de recursos y la capacidad de respuesta.
\item \textbf{Sharding (Fragmentación o particionado)}: Consiste en dividir una base de datos o conjunto de datos grande en "fragmentos". Cada shard maneja un subconjunto de datos. Esta estrategia permite distribuir la carga entre varios servidores o bases de datos, lo que mejora la capacidad de manejar grandes cantidades de datos y mejora la eficiencia del acceso a la información.
\end{itemize}
\subsection{Modifiability \small{(Modificabilidad)} }
Se refiere al costo y la facilidad con la que se pueden realizar cambios en el sistema sin afectar su funcionamiento y sin requerir mucho trabajo.
La modificabilidad tiene una serie de características específicas que describen cómo el sistema puede modificarse o ser extendido para adaptarse a nuevos requisitos o necesidades sin afectar su funcionamiento.
Estas caracteristicas son:
\begin{itemize}
\item \textbf{Extensibility (extensibilidad)}: Agregar funcionalidad al sistema (estática o
dinámicamente).
\item \textbf{Configurability (configurabilidad)}: Realizar cambios de los componentes post-deployment, de forma que puedan realizar otro tipo de servicios.
\item \textbf{Evolvability (evolucionabilidad)}: Modificar un componente sin impactar negativamente
en otros.
\item \textbf{Customizability (personalización)}: Extensiones de un cliente sin impactar en otros clientes del mismo componente.
\item \textbf{Reusability (Reusabilidad)}: Utilizar sus componentes en otras aplicaciones, sin
modificación.
\end{itemize}
Ajá muy lindo pero ¿que puede llegar a afectar la modificabilidad? Hay algunos parámetros que lo hacen y son los siguientes:
\begin{itemize}
\item \textbf{Tamaño del modulo}: Un módulo grande y complejo tiende a ser menos modificable que uno más pequeño y enfocado en una sola responsabilidad.
\item \textbf{Cohesión}: Un módulo con baja cohesión puede tener funcionalidades que no están estrechamente relacionadas. Si se requiere un cambio en una de estas funcionalidades, es probable que se deban realizar modificaciones en otras partes del módulo que no están directamente afectadas por el cambio. Esto complica todo.
\item \textbf{Acoplamiento}: Las dependencias entre los módulos son fuertes cuando tienen un alto acoplamiento. Un cambio en un módulo puede afectar a otros módulos que dependen de él o que él depende. Esto puede conducir a una cadena de cambios en cascada en la que varios módulos deben ajustarse para adaptarse al cambio inicial.
\item \textbf{Binding time}: Una inflexibilidad en el futuro puede ser el resultado de tomar decisiones de diseño en etapas tempranas del desarrollo del sistema. Es posible que no se hayan tenido en cuenta todos los requisitos futuros o cambios en el entorno si las decisiones se toman de manera prematura.
\end{itemize}
\subsubsection{Tácticas}
\begin{itemize}
\item \textbf{Reduce module size}
\begin{enumerate}
\item \textbf{Split Module}: Dividir un módulo grande y complejo en módulos más pequeños y específicos para mejorar la claridad y facilitar la modificación individual de cada componente sin afectar los demás.
\end{enumerate}
\item \textbf{Increase cohesion (semantic coherence)}:
\begin{enumerate}
\item \textbf{Analizar propósitos de las
responsabilidades de un módulo}
\item \textbf{Hipotetizar probables cambios}
\end{enumerate}
\item \textbf{Reduce coupling:}
\begin{enumerate}
\item \textbf{Encapsulate: API}: Al proporcionar una interfaz bien definida a través de la cual los módulos se comunican entre sí, se reduce el acoplamiento.
\item \textbf{Intermediary (pub-sub, shared repo, dynamic service lookup, etc)}: Introducir intermediarios o componentes compartidos puede ayudar a desacoplar los módulos y reducir las dependencias directas.
\item \textbf{Restrict dependencies (layers, wrappers)}: Al establecer capas o envoltorios que limiten las dependencias entre módulos, se disminuye la propagación de cambios y se mejora la independencia entre ellos.
\item \textbf{Refactor (factorizar responsabilidades comunes))}: La identificación de funcionalidades comunes y la factorización de estas en módulos independientes fomenta la reutilización y evita la duplicación de código, lo que facilita realizar cambios sin afectar varias partes del sistema.
\item \textbf{Abstract common services}: Al proporcionar servicios comunes como abstracciones, se mejora la adaptabilidad del sistema al modificar la implementación interna de los servicios sin afectar los módulos que los utilizan.
\end{enumerate}
\item \textbf{Defer Binding:}
Las decisiones de enlace, como la asignación de componentes específicos, deben retrasarse hasta que sea necesario. Al hacerlo, se mantiene la flexibilidad del sistema, lo que permite cambiar el enlace sin alterar el código fuente principal. Esto hace más sencillo cambiar y mantener el sistema a lo largo del tiempo.
\end{itemize}
\subsection{Visibility \small{(Visibilidad)} }\label{sec:visibilidad}
Se refiere a la capacidad de un sistema de software para proporcionar información clara, relevante y comprensible sobre su funcionamiento interno y comportamiento externo. Por lo tanto, la visibilidad se refiere a la capacidad de observar y comprender lo que está sucediendo dentro del sistema y cómo interactúa con su entorno.
Un sistema que tiene una alta visibilidad puede ofrecer herramientas y mecanismos, como por ejemplo:
\begin{enumerate}
\item \textbf{Monitorear y registrar datos de rendimiento}
\item \textbf{Registrar eventos y excepciones que ocurran en el sistema}
\item \textbf{Permitir la trazabilidad y el seguimiento de transacciones}
\item \textbf{Proporcionar métricas y estadísticas útiles}
\item \textbf{interfaces y paneles de control para visualizar el estado del sistema y su funcionamiento en tiempo real}
\end{enumerate}
\subsection{Security \small{(Seguridad)}}
Se refiere a la capacidad de un sistema para proteger sus recursos y datos contra accesos no autorizados, manipulación maliciosa y garantizar la confidencialidad, integridad, disponibilidad y autenticidad de la información y los servicios que brinda.
Esta característica tiene varios aspectos importantes. Las dimensiones o componentes fundamentales que componen el atributo se denominan aspectos. Y ¿cuales son estos aspectos claves? Son los siguientes:
\begin{enumerate}
\item \textbf{Confidentiality}: Proteger datos/servicios de accesos
no autorizados
\item \textbf{Integrity}: Datos/servicios no sujetos a manipulación no autorizada.
\item \textbf{Availability}: Sistema disponible para su uso legítimo.
\item \textbf{Authentication}: Verificación de identidad.
\item \textbf{Authorization}: Concesión de privilegios para ejecutar tareas.
\item \textbf{Non-repudiation}: Remitente y destinatario no deberían poder negar el intercambio de mensajes
\end{enumerate}
\subsubsection{Tácticas}
Para éste atributo, podemos organizar las tácticas en 4 categorías: detección de ataques, resistencia, reacción y recuperación.
\begin{itemize}
\item \textbf{Detección de ataques}
\begin{enumerate}
\item \textbf{Intrusion (detección basada en firmas)}: Se utiliza para identificar patrones de comportamiento relacionados con intrusiones conocidas, identificando actividades maliciosas a través de comparaciones con firmas o patrones previamente conocidos.
\item \textbf{Service Denial (comparación de patrones)}: El objetivo es identificar ataques que buscan negar o bloquear el acceso legítimo a servicios mediante el análisis de patrones de tráfico o comportamientos inusuales en las solicitudes.
\item \textbf{Verify Message Integrity (integridad de mensajes)}: Se utilizan técnicas de verificación como checksums o hashes para asegurarse de que los mensajes no han sido alterados o modificados durante la transmisión o el procesamiento.
\item \textbf{Detect Message Delay (MITM)}: Se enfoca en detectar posibles ataques de intermediarios maliciosos, también conocidos como "hombre en el medio", que pueden retrasar o manipular la entrega de mensajes entre dos partes.
\end{enumerate}
\item \textbf{Resistencia}:
\begin{enumerate}
\item \textbf{Identify, Authenticate, Authorize actors (identificar, autenticar y autorizar actores)}: implica verificar y validar la identidad de los usuarios o componentes del sistema antes de concederles acceso o privilegios específicos.
\item \textbf{Limit access (limitar acceso)}: Se refiere a limitar y controlar minuciosamente el acceso de los usuarios o componentes a los recursos y servicios que necesitan para sus funciones autorizadas.
\item \textbf{Limit exposure (reducir exposición)}: Implica limitar y restringir la exposición de API y servicios a través de cortafuegos y configuraciones de seguridad apropiadas para reducir la superficie de ataque del sistema.
\item \textbf{Encrypt data (encriptar datos)}: Se refiere al uso de métodos de cifrado para proteger información confidencial durante el almacenamiento o la transmisión, asegurando que solo aquellos autorizados puedan acceder a ella.
\end{enumerate}
\item \textbf{Reacción:}
\begin{enumerate}
\item \textbf{Revoke access (revocar acceso)}: Implica revocar el acceso de los usuarios o componentes involucrados en caso de detectar actividades maliciosas o no autorizadas.
\item \textbf{Lock computer (bloquear equipo))}: Se puede bloquear un computadora o sistema en respuesta a intentos fallidos de autenticación o actividades sospechosas.
\item \textbf{Inform actors (informar actores)}: Significa informar a los usuarios o partes afectadas sobre actividades sospechosas o eventos de seguridad para que tomen medidas.
\end{enumerate}
\item \textbf{Recuperación:}
\begin{enumerate}
\item \textbf{Audit Trail (registro de auditoría)}: Se refiere al mantenimiento de un registro detallado de eventos y actividades del sistema. Esto facilita la identificación y el análisis de posibles brechas de seguridad y permite la reconstrucción de eventos después de un ataque.
\item \textbf{Restore (restaurar)}: esta táctica está relacionada con las tácticas de disponibilidad y tiene como objetivo restaurar rápidamente los servicios y recursos afectados por un ataque para que el sistema vuelva a un estado funcional normal.
\end{enumerate}
\end{itemize}
\subsection{Testability \small{(Testeabilidad)}}
Se refiere a la facilidad con la que un sistema o aplicación puede ser probado para verificar su funcionamiento correcto y detectar errores o defectos potenciales. En otras palabras, se refiere a la facilidad con la que pueden descubrirse los bugs.
\subsubsection{Tácticas}
Las tácticas para éste atributo se pueden categorizar en dos enfoques: Control and Observe State, y Limit complexity.
\begin{itemize}
\item \textbf{Control and Observe State}:
Esta estrategia se centra en brindar herramientas y procedimientos para controlar y observar el estado interno del sistema durante las pruebas.
Algunas estrategias específicas son:
\begin{enumerate}
\item \textbf{Specialized Interfaces}: Crear interfaces especializadas, como métodos "Report()" o niveles de detalle en el registro de información (output/logging verbosity), que permitan a los testers obtener información relevante sobre el comportamiento del sistema durante las pruebas.
\item \textbf{Performance Instrumentation}: Incluye instrumentación de rendimiento que registra datos pertinentes, como tiempos de ejecución o recursos utilizados, para analizar el rendimiento del sistema bajo diferentes escenarios de prueba.
\item \textbf{Resource Monitoring}: Vigila los recursos del sistema, como el uso de memoria o CPU, para detectar problemas de rendimiento o agotamiento de recursos.
\item \textbf{Record/Playback}:Capturar la entrada (input) de una interfaz del sistema y luego reproducirla durante las pruebas, lo que permite recrear escenarios específicos y verificar resultados consistentes.
\item \textbf{Sandbox}: Aislar una instancia del sistema en un entorno de sandbox\footnote{Un entorno sandbox es un espacio controlado y aislado donde las aplicaciones o programas se ejecutan de forma separada del sistema principal. Este entorno protege y protege el sistema operativo y los recursos del sistema, lo que permite que las aplicaciones funcionen de manera segura sin dañar el funcionamiento del sistema principal.} para virtualizar recursos como el reloj del sistema, lo que facilita la simulación de condiciones particulares para pruebas.
\item \textbf{Assertions}: Se incluyen en el código para garantizar que ciertos estados o condiciones se cumplan durante las pruebas, detectando automáticamente estados fallidos.
\end{enumerate}
\item \textbf{Limit complexity}:
El objetivo de esta estrategia es reducir la complejidad del sistema para que sea más comprensible y manejable durante las pruebas.
Algunas estrategias específicas son:
\begin{enumerate}
\item \textbf{Structural Complexity}: Reduce las dependencias entre componentes y módulos, lo que facilita la separación de unidades específicas para pruebas unitarias y mejora la identificación de errores.
\item \textbf{Limit Non-determinism}: Reduce las partes del sistema que muestran comportamiento no determinista (comportamiento que cambia con cada ejecución), lo que permite obtener resultados más predecibles y consistentes durante las pruebas.
\end{enumerate}
\end{itemize}
\subsection{Usability \small{(Usabilidad)}}
Es la facilidad con la que el usuario puede realizar una tarea deseada, y el tipo de soporte a usuarios que el sistema provee.
\subsubsection{Tácticas}
Las tácticas para éste atributo se pueden categorizar en dos enfoques: Support User Initiative, y Support System Initiative.
\begin{itemize}
\item \textbf{Support User Initiative}:
Prioriza la libertad y el control del usuario en el sistema. Se trata de dar al usuario el control sobre lo que hace y elige en la interfaz.
Algunas formas de utilizar esta estrategia incluyen:
\begin{enumerate}
\item \textbf{Cancel}: Ofrecer al usuario la capacidad de cancelar una acción o proceso en curso sin tener consecuencias negativas.
\item \textbf{Undo}: Permitir al usuario cancelar una acción anterior y restaurar cambios no deseados.
\item \textbf{Pause/Resume}: Dar la opción de pausar un proceso o una tarea y luego reanudarlo más tarde, lo que es particularmente útil para tareas largas o complejas.
\item \textbf{Aggregate}: Permitir que el usuario realice operaciones en lotes que afecten a múltiples elementos o entidades a la vez en lugar de tener que realizar cada operación individualmente.
\end{enumerate}
\item \textbf{Support System Initiative}:
Al utilizar la información del contexto y del usuario, esta estrategia tiene como objetivo mejorar el rendimiento del sistema.
Algunas estrategias específicas son:
\begin{enumerate}
\item \textbf{Task Model (Modelo de Tareas)}: Para anticipar las necesidades del usuario y brindarle una asistencia más efectiva, el sistema puede utilizar un modelo de las tareas que realiza el usuario. Un autocorrector basado en el texto del documento, por ejemplo, que detecta errores comunes y ofrece sugerencias para corregirlos al usuario.
\item \textbf{User Model (Modelo del Usuario)}: El sistema puede crear un perfil o modelo del usuario basado en el comportamiento, las preferencias o el conocimiento previo del usuario. Esto permite que la experiencia del usuario se adapte a sus necesidades particulares.
\item \textbf{System Model (Modelo del Sistema)}: El sistema tiene la capacidad de emplear un modelo interno para anticipar o calcular el tiempo restante en una tarea, permitiendo así que el usuario pueda planificar sus actividades y administrar su tiempo de manera más eficiente.
\end{enumerate}
\end{itemize}
\subsection{Interoperability \small{(Interoperabilidad)}}
Es la capacidad de sistemas o componentes para trabajar juntos de manera efectiva y eficiente, permitiendo el intercambio y comprensión de datos e información a través de interfaces comunes.
\subsubsection{Tácticas}
Las tácticas para éste atributo se pueden categorizar en dos enfoques: Locate, y Manage Interfaces.
\begin{itemize}
\item \textbf{Locate}:
\begin{enumerate}
\item \textbf{Discover Service (Descubrir servicio)}: Se refiere a la capacidad de encontrar y localizar un servicio específico entre una variedad de servicios disponibles, ya sea durante el proceso o durante la interacción.
\end{enumerate}
\item \textbf{Manage Interfaces}:
\begin{enumerate}
\item \textbf{Orchestrate (Orquestar)}: Se refiere a la coordinación y organización de la secuencia de llamadas de servicios o tareas para que trabajen de manera eficiente y adecuada.
\item \textbf{Tailor Interface (Adaptar interfaz)}: Permite personalizar la interfaz y las funcionalidades del servicio según las necesidades y características del cliente o usuario.
\end{enumerate}
\end{itemize}
\subsection{Portability \small{(Portabilidad)}}
Se refiere a la capacidad de un programa, aplicación o sistema para funcionar o transferirse entre diferentes entornos o plataformas sin realizar cambios significativos.
En otras palabras, si un software o sistema puede funcionar en una variedad de sistemas operativos, arquitecturas de hardware o entornos sin requerir una reescritura o adaptación significativa, se considera que es portátil.
\subsection{Elasticity \small{(Elasticidad)}}
Se refiere a la capacidad de un sistema para adaptarse y ajustar sus recursos de manera dinámica y automática en respuesta a cambios en la carga de trabajo o demanda.
\subsection{Manageability \small{(Manejabilidad)}}
Se refiere a la capacidad de un sistema, aplicación o dispositivo para ser administrado y controlado con facilidad por administradores, usuarios o herramientas automatizadas.
\subsection{Reliability \small{(Fiabilidad)}}
se refiere a la capacidad de un sistema, dispositivo o proceso para realizar una función o tarea durante un período de tiempo determinado de manera precisa, consistente y sin fallas.
En otras palabras, un sistema fiable es aquel que puede mantener el rendimiento y la operación esperados incluso en circunstancias adversas o imprevistas.
\section{Estilos de arquitectura}
Un estilo arquitectónico es un conjunto coordinado de restricciones arquitectónicas que restringe las
funciones/características de los elementos arquitectónicos y las relaciones permitidas entre esos elementos, dentro de cualquier arquitectura que se ajusta a ese estilo.
Los estilos arquitectónicos son métodos que combinan estructuras de soluciones arquitectónicas especificando un conjunto de componentes y sus responsabilidades. Además, establecen reglas que regulan cómo se relacionan estos elementos entre sí. Estos estilos permiten evaluar una variedad de arquitecturas alternativas, identificando sus ventajas y desventajas en función de las distintas características de calidad requeridas.
Los estilos arquitectónicos se pueden clasificar de la siguiente manera (ojo, no es una clasificacion completa, sino una muestra representantiva):
\begin{itemize}
\item {Data Flow Styles}
\item {Replication Styles}
\item {Hierarchical Styles}
\item {Mobile Code Styles}
\item {Peer to Peer Styles}
\end{itemize}
\begin{figure}[h]
\centering
\includegraphics[width=1\textwidth]{clasificacion_arquitecturas.png}
\caption{Clasificación de las arquitecturas}
\end{figure}
\subsection{Replication Styles}
\subsubsection{Replicated Repository (RR)}
Son una arquitectura en la que varios procesos brindan el mismo servicio. Los servidores descentralizados trabajan juntos para dar a los clientes la impresión de que hay un solo servidor central en lugar de un servidor centralizado.
Este enfoque se emplea en sistemas de archivos distribuidos,y sistemas de control de versiones, como CVS/SVN (local), donde múltiples servidores colaboran para garantizar el rendimiento y la disponibilidad.
\paragraph{Beneficios:}
¿Cuales son las ventajas de esto?
\begin{itemize}
\item {\textbf{Escalabilidad}}: Permite manejar picos de carga, usuarios y transacciones más grandes sin comprometer el rendimiento del sistema.
\item {\textbf{Performance}}: Como los datos se pueden obtener de los servidores más cercanos al cliente, se reduce la latencia de las solicitudes normales. Además, permite trabajar en modo offline en situaciones en las que no se puede conectar al servidor central.
\item {\textbf{Confiabilidad}}: Una falla en uno de los servidores no causa una caída del servicio porque otros servidores pueden continuar brindando el servicio.
\item {\textbf{Simplicidad}}: La simplicidad en la manipulación de datos replicados a nivel local compensa la complejidad de la replicación, lo que facilita el uso del sistema para los clientes.
\end{itemize}
Genial muy lindo, pero una preocupación importante en esta arquitectura es mantener la consistencia de los datos. Para evitar inconsistencias y conflictos, es crucial asegurarse de que los datos replicados siempre estén sincronizados y actualizados entre los servidores.
\subsubsection{Cache (\$)}
Es una técnica de arquitectura que implica la replicación del resultado de una solicitud en un sistema, permitiendo que este resultado sea utilizado en futuras solicitudes similares. Es una variante del concepto de "Repositorios replicados" (RR) y se usa principalmente en situaciones en las que el conjunto de datos posible es mayor de lo que el cliente puede manejar o cuando el acceso completo al repositorio es innecesario.
\paragraph{Implementaciones}
\begin{itemize}
\item {\textbf{Lazy Population (Población perezosa)}}: En este método, la caché se llena o actualiza solo cuando es necesario; por ejemplo, cuando un cliente hace una solicitud y el resultado no está en la caché. Esto permite ahorrar recursos al replicar solo la información necesaria.
\item {\textbf{Active Population (Población activa)}}: En este caso, la caché se llena de manera proactiva, anticipando las solicitudes que es probable que se realicen en el futuro. Esta táctica tiene como objetivo mejorar aún más el rendimiento al preparar los datos antes de la solicitud.
\end{itemize}
\paragraph{Beneficios:}
El Cache es ampliamente utilizada en aplicaciones web para mejorar el rendimiento y reducir la latencia. Algunos beneficios de su implementación son:
\begin{itemize}
\item {\textbf{Performance}}: Aunque no ofrece mejoras tan significativas como la replicación de repositorios, aún así mejora el rendimiento del sistema al reducir el tiempo de respuesta de las solicitudes.
\item {\textbf{Simplicidad}}: es más sencillo de implementar en comparación con la replicación de repositorios, lo que la convierte en una opción atractiva para sistemas con requerimientos de recursos más modestos.
\end{itemize}
El cache requiere menos recursos de procesamiento y almacenamiento en comparación con la replicación de repositorios (RR), ya que solo replica datos relevantes y puede transmitir solo cuando sea necesario. Debido a la naturaleza selectiva de la caché, sin embargo, los beneficios en términos de rendimiento percibido pueden ser menores que los RR.
\subsection{Hierarchical Styles}
\subsubsection{Client Server (CS)}
El "servidor-cliente" (servidor cliente, CS) es el estilo arquitectónico más común para aplicaciones basadas en red. El servidor y el cliente son los dos componentes principales de la arquitectura de este estilo.
El componente que ofrece servicios y responde a las peticiones de los clientes es el servidor. Es responsable de enviar o rechazar las solicitudes y responder a ellas.
El componente llamado cliente solicita servicios al servidor a través de un conector. El cliente sabe del servidor, pero no sabe de todos los clientes. Un servidor puede manejar a muchos clientes.
Este estilo se destaca por la clara separación de responsabilidades entre el servidor y el cliente. El cliente se encarga de solicitar servicios y el servidor de proporcionarlos. Esta separación simplifica el diseño y facilita la evolución de ambos componentes de forma independiente.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Escalabilidad}}: Debido a que el servidor es el componente que generalmente requiere una mayor capacidad y recursos para atender a múltiples clientes, la arquitectura "Client-Server" permite un crecimiento más sencillo del sistema.
\item {\textbf{Simplicidad}}: La separación de funciones hace que el diseño general del sistema sea más sencillo, lo que facilita el desarrollo y mantenimiento del software.
\item {\textbf{Evolucionabilidad}}: La separación de funciones permite que el cliente y el servidor evolucionen de manera independiente. Siempre y cuando se mantenga la interfaz entre ellos, las modificaciones en uno de los componentes no necesariamente afectarán al otro.
\end{itemize}
\subsubsection{Layered Server (LS)}
Es un estilo arquitectónico en el que las capas jerárquicas organizan el sistema. Cada capa proporciona servicios a la capa superior mientras que la capa inferior los utiliza. Este método oculta las capas internas a las capas superiores para reducir el acoplamiento entre las diferentes partes del sistema.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Evolucionabilidad}}: Permite evolucionar cada capa de manera independiente sin afectar a las demás.
\item {\textbf{Extensibilidad}}: Es posible agregar nuevas capas a medida que se requieran nuevas funcionalidades o servicios en el sistema.
\item {\textbf{Reusabilidad}}: Las capas pueden ser diseñadas de forma modular y reutilizarse en diferentes sistemas o contexto.
\item {\textbf{Portabilidad}}: Las capas se pueden portar y utilizar en diferentes sistemas o plataformas.
\end{itemize}
Sin embargo presenta una desventaja en la \textbf{Performance}, porque la adición de capas puede introducir overhead y latencia en el sistema.
\subsubsection{Layered Client System (LCS)}
El enfoque arquitectónico "Cliente Servidores de capas" (LCS) combina el concepto de capas con el estilo "Cliente Servidores de capas" (CS) en sistemas basados en red. Para proporcionar una estructura más jerárquica y modular, en este caso, las arquitecturas CS se organizan en capas.
El "Reverse Proxy", también conocido como proxy inverso, es una capa de aplicación accesible desde varios clientes y es un componente crucial de las arquitecturas LCS. Las solicitudes de los clientes son recibidas por esta capa y luego enviadas a los componentes del servidor. Además, el "Reverse Proxy" tiene la capacidad de traducir o modificar las solicitudes antes de enviarlas a los servidores, lo que mejora la funcionalidad.
En cuestión a los beneficios, se suman los beneficios entre CS y LS.
\subsubsection{Load Balancer}\label{sec:load_balancer}
Es una parte importante de las arquitecturas de sistemas distribuidos que se encarga de recibir solicitudes (requests) de los clientes y distribuirlas entre un grupo de servidores, luego direccionando la respuesta del servidor seleccionado al cliente correspondiente.
Su objetivo principal es mejorar el rendimiento y la disponibilidad del sistema asegurándose de que el tráfico de las solicitudes se distribuya de manera equitativa y se gestione de manera eficiente entre los servidores.
La relación entre el load balancer y arquitectura stateless, es que al servidor al que se envía una solicitud específica no importa, ya que cada solicitud incluye todos los datos necesarios para su procesamiento de manera independiente. Esto facilita la distribución eficiente de la carga y contribuye a la escalabilidad y la estabilidad del sistema al eliminar la necesidad de preocuparse por la persistencia del estado en los servidores individuales.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Escalabilidad}}: Soporta un volumen de usuarios/requests más alto.
\item {\textbf{Elasticidad}}: Según el caso, podría escalar acorde a la demanda.
\item {\textbf{Disponibilidad}}: Las capas pueden ser diseñadas de forma modular y reutilizarse en diferentes sistemas o contexto.
\item {\textbf{Fiabilidad}}: El balanceador de carga mejora la confiabilidad del sistema al eliminar un solo punto de falla al distribuir el tráfico entre varios servidores.
\item {\textbf{Performance}}: Mejor uso de los recursos escasos. En algunos casos, el balanceador de carga puede tratar ciertos tipos de solicitudes de manera diferenciada.
\item {\textbf{UX}}: Reduce el número de errores visibles por el usuario.
\end{itemize}
\subsubsection{Reverse Proxy}
Es una parte importante de las arquitecturas de sistemas distribuidos que sirve como intermediario entre los servidores reales y los clientes. Su función principal es recibir solicitudes de clientes, reenviarlas al servidor correspondiente y devolver la respuesta del servidor al cliente. Una de sus características principales es ocultar la identidad de los servidores reales, actuando como una cara pública o fachada del sistema.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Seguridad}}: Actúa como una barrera de seguridad que oculta la identidad y ubicación de los servidores reales. Al hacerlo, protege los servidores de posibles ataques directos y reduce la exposición de vulnerabilidades. Esconde los servidores asi ecita explotar vulnerabilidades y puede implementar mecanismos de proteccion contra ataques DoS
\item {\textbf{Escalabilidad}}: Permite una mayor flexibilidad en el manejo de recursos, ya que puede agregar o eliminar servidores reales de manera dinámica y transparente.
\item {\textbf{Performance}}: Mejora el rendimiento del sistema al realizar técnicas de aceleración web, como el almacenamiento en caché, compresión y terminación SSL.
\end{itemize}
\subsubsection{Client-Stateless-Server (CSS)}\label{sec:client-statless-server}
Es un método arquitectónico que proviene del estilo "Client-Server" (CS), pero tiene una limitación: no se puede almacenar el estado de la sesión en el componente servidor. En este caso, el propio cliente debe proporcionar toda la información necesaria para comprender las solicitudes del cliente, y el servidor no mantiene ningún tipo de contexto o estado de la sesión. El cliente tiene todo el control sobre el estado.
¿Que es el estado? Cualquier información sobre la sesión del cliente que el servidor debe recordar y mantener entre varias solicitudes se conoce como estado.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Visibilidad}}: Al no mantener el estado, simplifica la tarea de un sistema de monitoreo.
\item {\textbf{Confiabilidad}}: Al no depender del estado del servidor, el CSS facilita la recuperación ante fallos parciales o interrupciones.
\item {\textbf{Escalabilidad}}: Permite asignar libremente un servidor para procesar una solicitud.
\end{itemize}
\paragraph{Desventajas}
\begin{itemize}
\item {\textbf{Performance}}: Al transmitir toda la información requerida con cada solicitud, puede haber una transmisión de datos repetitiva a través de la red, lo que puede afectar el rendimiento en comparación con sistemas que almacenan el estado en el servidor.
\end{itemize}
\subsubsection{Client-Cache-Stateless-Server(C\$SS)}
Es un enfoque arquitectónico que combina características de "Client Stateless Server" (CSS) y Client Cache(\$). Esta arquitectura incorpora una capa de mediadores de caché adicional para mejorar el rendimiento y la eficiencia del sistema.
Los clientes interactúan con un servidor que no mantiene estado (CSS) en C\$SS, lo que significa que no almacena datos de sesión entre solicitudes. El servidor responde de manera independiente y sin dependencia de estados anteriores a cada solicitud del cliente, que contiene toda la información necesaria para ser comprendida y procesada.
Sin embargo, para mejorar el rendimiento y la eficiencia, se agrega la funcionalidad de caché (Client Cache, \$) en algún lugar de la arquitectura. Los mediadores\footnote{En un sistema distribuido, los mediadores de caché, también conocidos como "proxys de caché" o "servidores de caché", son componentes que actúan como intermediarios entre los clientes y los servidores.} de caché almacenan copias temporales de respuestas a solicitudes previas para que, si un cliente hace una solicitud idéntica o similar a una que ya ha sido atendida, el servidor pueda evitar repetir todo el procesamiento y simplemente devolver la respuesta desde la caché.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Performance}}: El uso del caché para almacenar respuestas previas reduce el tiempo y los recursos necesarios para procesar solicitudes repetitivas.
\end{itemize}
\subsubsection{Layered-Client-Cache-Stateless-Server (LC\$SS)}
Es un estilo arquitectónico que combina características de los estilos "Layered Client Server" y "Client Cache Stateless Server". Para mejorar el rendimiento, la eficiencia y la escalabilidad del sistema, se agregan componentes de proxy y caché en esta arquitectura.
El LC\$SS utiliza un enfoque de capas jerárquicas donde los clientes interactúan con un servidor que no mantiene estado (Client Stateless Server, CSS), y cada solicitud del cliente contiene toda la información necesaria para comprender y procesar. Además, incluye componentes de caché que almacenan copias temporales de respuestas previamente atendidas, así como componentes de proxy que funcionan como intermediarios entre los clientes y los servidores reales.
En relación a los beneficios y contras, se suman ambos aspectos de LCS y C\$SS.
\subsubsection{Remote Session (RS)}
Proviene del estilo "Client-Server" (CS) y tiene como objetivo reducir la complejidad y aumentar la reutilización de los componentes del cliente. En esta arquitectura, los clientes inician una sesión en el servidor, solicitan sus servicios y cierran la sesión al final.
Es un estilo arquitectónico que simplifica la interacción del cliente con el servidor durante una sesión activa al centralizar el estado de la aplicación en el servidor.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Simplicidad}}: Es es más fácil de mantener y gestionar, ya que la interfaz del servidor es centralizada y los clientes solo necesitan interactuar con el servidor durante la sesión activa.
\end{itemize}
\paragraph{Desventajas}
\begin{itemize}
\item {\textbf{Escalabilidad}}: El server requiere mantener el estado de la app.
\item {\textbf{Visibilidad}}: Dado que el estado de la aplicación se mantiene completamente en el servidor, el monitor o el sistema de monitoreo debe tener acceso al estado completo del servidor.
\end{itemize}
\subsubsection{Remote Data Access (RDA)}
Es un estilo arquitectónico que se deriva del estilo "Client-Server" (CS) y busca distribuir el estado de la aplicación entre el cliente y el servidor. En esta arquitectura, el cliente envía consultas al servidor remoto en un formato estándar, como SQL, y el servidor procesa estas consultas en un workspace para obtener un conjunto potencialmente grande de datos. Luego, el cliente puede realizar más operaciones sobre este dataset sin necesidad de transmitir todos los datos nuevamente.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Performance}}: Datasets grandes pueden ser reducidos del lado del
servidor, sin transmisión de datos.
\item {\textbf{Visibilidad}}: El uso de consultas de lenguaje estándar como SQL permite que el cliente y el servidor se comuniquen de manera consistente. Sin embargo, esto también podría requerir que el monitor tenga acceso al estado del servidor.
\end{itemize}
\paragraph{Desventajas}
\begin{itemize}
\item {\textbf{Escalabilidad}}: El server requiere mantener el estado de la app.
\item {\textbf{Confiabilidad}}: Si una operación falla, el workspace puede quedar en un estado desconocido.
\end{itemize}
\subsection{Mobile Code Styles}
\subsubsection{Virtual Machine (VM)}
Todos los estilos de Mobile Code se basan en esta arquitectura. Este método asegura la confiabilidad y la seguridad al ejecutar el código en un ambiente controlado proporcionado por la máquina virtual.
Un motor de lenguaje de scripting como Perl o Python es un ejemplo común de la arquitectura de la máquina virtual. En este caso, la máquina virtual del lenguaje interpreta y ejecuta el código escrito en el lenguaje de scripting, lo que crea un ambiente controlado para la ejecución del código.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Portabilidad}}: Separa el código de su implementación/aplicación en
una plataforma específica.
\item {\textbf{Extensibilidad}}: Es más fácil crear funcionalidad sobre una plataforma
genérica.
\end{itemize}
\paragraph{Desventajas}
\begin{itemize}
\item {\textbf{Visibilidad}}: Es difícil saber que va a hacer un ejecutable mirando
sólo su código fuente.
\end{itemize}
\subsubsection{Remote Evaluation (REV)}
Es una mezcla de características de "máquina virtual" (VM) y "Client-Server" (CS). En esta arquitectura, el cliente sabe cómo (know-how) ejecutar un servicio, pero carece de los recursos necesarios para hacerlo eficientemente, como CPU, memoria o acceso a una fuente de datos. El cliente envía el "conocimiento" o el código requerido al servidor para que este último lo ejecute utilizando sus propios recursos en lugar de ejecutar la operación localmente. El cliente recibe el resultado una vez que se completa la ejecución en el servidor.
SQL es un ejemplo común de esta arquitectura. El cliente envía una consulta SQL al servidor en este caso, que puede leer y ejecutar el código SQL para recuperar los datos de una base de datos necesarios.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Performance}}: En lugar de usar los recursos del servidor para realizar la operación del lado del cliente, donde podría haber falta de recursos, se utilizan los recursos del servidor.
\item {\textbf{Extensibilidad}}: Los componentes del servidor se pueden ajustar para satisfacer las necesidades particulares del cliente.
\end{itemize}
\paragraph{Desventajas}
\begin{itemize}
\item {\textbf{Visibilidad}}: El cliente envía código en lugar de un simple request.
\item {\textbf{Escalabilidad}}: A mayor carga, mayor consumo de recursos.
\item {\textbf{Confiabilidad}}: El servidor tiene menos control de la ejecución.
\end{itemize}
\subsubsection{Code on Demand (COD)}\label{sec:code_on_demand}
Esta arquitectura, la cual deriva de VM y CS, el cliente tiene los recursos (como CPU, memoria o acceso a una fuente de datos) para ejecutar un servicio, pero no tiene el conocimiento o la experiencia necesarios para realizar la operación de manera efectiva. El cliente envía una solicitud al servidor pidiéndole el código que representa el "know-how" necesario en lugar de enviar los datos al servidor para que se realice el procesamiento. El cliente ejecuta el código del servidor localmente para completar la operación.
JavaScript (JS) en aplicaciones web es un ejemplo común de la arquitectura "Code on Demand". En este caso, el cliente tiene la capacidad de ejecutar código JavaScript, pero el servidor puede proporcionar scripts adicionales que se ejecutan localmente en el navegador del cliente para mejorar la experiencia del usuario o proporcionar funcionalidades adicionales.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Configurabilidad y Extensibilidad}}: Permite agregar nuevas funcionalidades a un cliente ya desplegado sin cambiar el código fuente original.
\item {\textbf{Escalabilidad}}: Utilizar los recursos de los clientes para ejecutar el código, reduce la carga en el servidor.
\item {\textbf{Performance}}: La ejecución se realiza interactuando localmente con el
cliente, sin necesidad del servidor.
\end{itemize}
\paragraph{Desventajas}
\begin{itemize}
\item {\textbf{Visibilidad}}: El servidor envía código al cliente en lugar de datos.
\end{itemize}
\subsubsection{Layered Code on Demand Client Cache Stateless Server (LCODC\$SS)}
Esta arquitectura deriva de LC\$SS + COD y se acerca más al concepto actual de la web y habla de casos en los que los navegadores permiten la ejecución de applets o extensiones de protocolos.
Como ejemplo, esta arquitectura podría ser un tipo de navegador web que permite la ejecución de extensiones o applets para mejorar la funcionalidad de las páginas web.
Es importante destacar no se relaciona directamente con protocolos específicos como HTTP o REST. Esto se debe a que se refiere más al concepto general de permitir que el servidor proporcione código ejecutable al cliente y que este lo ejecute localmente para aumentar sus capacidades y mejorar la interacción con el servidor o otras aplicaciones web.
\subsubsection{Mobile Agent (MA)}
Esta arquitectura combina las características REV y (COD). Un componente completo, que incluye su estado, código y datos, se mueve de un sitio remoto a otro mediante este método. Los agentes móviles pueden trabajar en ambos sentidos, es decir, pueden pasar del cliente al servidor ($c \to s$) o del servidor al cliente ($s \to $c), dependiendo de la situación.
Los agentes móviles ofrecen una gran flexibilidad en cuanto a cuándo y dónde hacer el movimiento. Por ejemplo, una aplicación en ejecución puede estar procesando una tarea específica y, en un momento determinado, decidir moverse a otra ubicación. Esto podría ocurrir para estar más cerca del próximo conjunto de datos o para aprovechar recursos específicos de otra máquina.
\subsection{Peer To Peer Styles}
\subsubsection{Event Based Integration (EBI)}
Es un estilo de integración de componentes en el que se utiliza un enfoque Peer-to-Peer para la comunicación entre los componentes. En lugar de invocar directamente a otros componentes, un componente puede publicar uno o más eventos de esta manera. En lugar de ser invocados directamente, otros componentes se registran para recibir notificaciones sobre eventos específicos que puedan ser relevantes para vos. El sistema invoca a todos los componentes registrados cuando se produce un evento.
Algunos ejemplos de EBI son: Smalltalk, MVC, Publisher/Subscriber.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Extensibilidad}}: Es fácil agregar nuevos componentes que respondan a
eventos existentes o nuevos.
\item {\textbf{Reusabilidad}}: Establece un mecanismo de integración y una interfaz
de eventos común.
\item {\textbf{Evolucionabilidad}}: Permite reemplazar componentes sin afectar a otros.
\item {\textbf{Performance}}: En algunos sistemas, principalmente dominados por
monitoreo, se elimina la necesidad de \textit{polling}.
\end{itemize}
\paragraph{Desventajas}
\begin{itemize}
\item {\textbf{Escalabilidad}}: La cantidad de notificaciones de eventos y la tormenta de
eventos pueden tener un impacto en el funcionamiento del sistema. Además, si no se gestiona adecuadamente, el filtrado de eventos puede agregar complejidad y crear puntos de falla únicos en el sistema.
\item {\textbf{Entendimiento}}: Difícil predecir qué ocurrirá ante un evento (ej. orden).
Tampoco se sabe si alguien responderá.
\end{itemize}
\subsubsection{Distributed Objects (DO)}
Es un estilo de arquitectura Peer-to-Peer que organiza el sistema como un conjunto de componentes interactivos que actúan como pares. Este estilo representa los componentes como objetos con un estado interno oculto o protegido, así como sus operaciones asociadas. Las invocaciones de operaciones permiten que los objetos se comuniquen entre sí y pueden provocar una serie de invocaciones en otros objetos.
Cada objeto funciona como una entidad abstracta que encapsula su estado interno y las operaciones que pueden realizar sobre ese estado.
Una operación en un objeto puede invocar operaciones en otros objetos, lo que puede dar lugar a cadenas de invocaciones que pueden extenderse a lo largo de varios objetos.
El estado de la aplicación se distribuye entre los objetos del sistema, lo que permite que diferentes partes del sistema mantengan su propio estado y trabajen juntas para lograr un objetivo común.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Evolucionabilidad}}: Los objetos tiene interfaz pública, estado privado.
\end{itemize}
\paragraph{Desventajas}
\begin{itemize}
\item {\textbf{Visibilidad}}: Es difícil obtener una vista general del estado y de la
actividad del sistema.
\end{itemize}
\subsubsection{Brokered Distributed Objects (BDO)}
Este estilo es una mezcla de los estilos "Distributed Objects" (DO) y y "Layered Client Server" (LCS). Tiene como objetivo resolver el problema de la identidad de los objetos distribuidos al agregar un intermediario (broker) que facilita la comunicación entre los objetos distribuidos.
El problema de la identidad se reduce ya que los clientes utilizan nombres de servicio generales en lugar de identidades específicas.
El broker se encarga de identificar la identidad del objeto específico al que se envía la solicitud cuando un cliente envía una solicitud con un nombre de servicio genérico.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Evolucionabilidad y Reusabilidad}}: Los nombres de servicio genéricos facilitan la reutilización y evolución de los componentes.
\end{itemize}
\paragraph{Desventajas}
\begin{itemize}
\item {\textbf{Eficienciay Performance percibida}}: Dado que cada solicitud debe pasar a través del intermediario para que se determine la identidad del objeto específico, el uso del intermediario introduce una mayor cantidad de interacciones de red.
\end{itemize}
\subsection{Data Centered Architectures}
Son un estilo arquitectónico en el que una estructura central de datos que almacena el estado del sistema es el componente principal. Este almacenamiento centralizado permite que los componentes independientes del sistema realicen sus operaciones y procesos.
El repositorio central puede variar según cómo se decida qué procesos ejecutar. El repositorio puede ser una \textbf{base de datos} que almacena los datos de entrada si el input stream decide/dispara los procesos a ejecutar.
Por otro lado, el repositorio puede ser conocido como \textbf{blackboard} si el estado actual del sistema determina qué procesos deben ejecutarse. En este caso, el repositorio es donde los componentes consultan y actualizan el estado compartido.
\subsubsection{Blackboard}
Es una arquitectura en la que un componente central llamado \textbf{blackboard} permite la comunicación entre múltiples fuentes de conocimiento.
El blackboard funciona como una estructura de datos compartida con información sobre cómo resolver un problema. En situaciones en las que la solución de un problema complejo requiere el aporte de conocimiento de diversas fuentes, se utiliza este estilo arquitectónico.
Veamos algunas características principales de esto:
\begin{itemize}
\item {\textbf{Fuentes de conocimiento}}: Son componentes independientes que tienen conocimientos específicos para abordar varios aspectos del problema. Cada fuente de conocimiento es responsable de analizar el estado actual del blackboard, proporcionar información relevante y realizar modificaciones en él.
\item {\textbf{Iteraciones para llegar a la solución}}: La solución de problemas es iterativa. El blackboard se modifica mientras las fuentes de conocimiento trabajan juntas.
\item {\textbf{Control coordinado por el estado del blackboard}}: La coordinación de las fuentes de conocimiento solo depende del estado actual del blackboard. Las fuentes de conocimiento responden oportunamente a los cambios del blackboard.
\end{itemize}
\begin{figure}[h]
\centering
\includegraphics[width=1\textwidth]{blackboard.png}
\caption{Representación del blackboard}
\end{figure}
\subsection{Data Flow Styles}
\subsubsection{Pipe \& Filter (PF)}
Este estilo se basa en la creación de flujos de datos de salida mediante el procesamiento de flujos de datos de entrada por parte de filtros independientes. El flujo de datos se procesa gradualmente y cada filtro es un componente independiente. Este estilo es adecuado para problemas que se dividen en etapas independientes y permite el desacoplamiento completo entre los filtros. Es útil para el procesamiento eficiente de grandes volúmenes de datos y facilita el desarrollo y la reutilización de componentes.
Sin embargo, el flujo de datos puede estar sobrecargado y el filtro más lento puede afectar el rendimiento.
Este estilo ve el sistema como una serie de transformaciones consecutivas. Es beneficioso cuando se puede abordar un problema mediante un flujo continuo de datos, como un "río". Permite medir el throughput del sistema, que es la cantidad de datos que puede procesar el sistema en un período de tiempo determinado. Una red puede ser representada por una tubería, donde la salida de un filtro puede ser la entrada de varios filtros, lo que permite un procesamiento de datos más complejo y eficiente.
\paragraph{Beneficios}
\begin{itemize}
\item {\textbf{Simplicidad}}: Se puede entender el sistema como una composición
simple del comportamiento de los filtros individuales.
\item {\textbf{Reusabilidad}}: Los filtros pueden reusarse y conectarse entre sí,
siempre que estén de acuerdo con sus interfaces.
\item {\textbf{Extensibilidad}}: Nuevos filtros pueden agregarse.
\item {\textbf{Evolucionabilidad}}: Los filtros pueden reemplazarse por una versión