kukuy 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.ssl +22 -0
- package/README.md +107 -171
- package/balancer.log +2 -0
- package/certs/auto/certificate.crt +22 -0
- package/certs/auto/private.key +28 -0
- package/kukuy-plugins/README.md +91 -0
- package/kukuy-plugins/ejemplo-plugin/index.js +39 -0
- package/kukuy-plugins/ejemplo-plugin/manifest.json +11 -0
- package/kukuy.js +51 -5
- package/package.json +8 -2
- package/servers_real.json +5 -0
- package/src/algorithms/IPHashAlgorithm.js +25 -13
- package/src/algorithms/RoundRobinAlgorithm.js +25 -27
- package/src/core/Balancer.js +201 -128
- package/src/core/ServerPool.js +46 -5
- package/src/extensibility/ExtendedFilterChain.js +90 -0
- package/src/extensibility/ExtendedHookManager.js +87 -0
- package/src/extensibility/PostStartupExtension.js +97 -0
- package/src/plugins/PluginManager.js +183 -0
- package/src/utils/HealthChecker.js +11 -5
- package/src/utils/ProfessionalMetrics.js +41 -24
- package/start-ssl-config.sh +24 -0
- package/start-ssl.sh +26 -0
- package/webpage/index.html +1 -1
- package/.ctagsd/ctagsd.json +0 -954
- package/.ctagsd/file_list.txt +0 -100
- package/.ctagsd/tags.db +0 -0
- package/CHANGELOG.md +0 -101
- package/LICENSE +0 -680
- package/captura.png +0 -0
- package/kukuy.workspace +0 -11
- package/restart-balancer.sh +0 -10
- package/scripts/load_test.py +0 -151
- package/stress-test.js +0 -190
package/.env.ssl
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Archivo de configuración para Kukuy en modo SSL
|
|
2
|
+
|
|
3
|
+
# Puerto para el servidor HTTPS
|
|
4
|
+
BALANCER_HTTPS_PORT=8443
|
|
5
|
+
|
|
6
|
+
# Ruta al certificado SSL
|
|
7
|
+
SSL_CERT_PATH=certs/auto/certificate.crt
|
|
8
|
+
|
|
9
|
+
# Ruta a la llave privada SSL
|
|
10
|
+
SSL_KEY_PATH=certs/auto/private.key
|
|
11
|
+
|
|
12
|
+
# Opcional: Puerto para el servidor HTTP (descomentar para habilitar)
|
|
13
|
+
# BALANCER_HTTP_PORT=8080
|
|
14
|
+
|
|
15
|
+
# Opcional: Habilitar modo HTTP junto con HTTPS
|
|
16
|
+
# ENABLE_HTTP=true
|
|
17
|
+
|
|
18
|
+
# Otros ajustes de configuración
|
|
19
|
+
LOG_LEVEL=info
|
|
20
|
+
HEALTH_CHECK_INTERVAL=30000
|
|
21
|
+
CONFIG_FILE_PATH=./servers_real.json
|
|
22
|
+
ROUTES_FILE_PATH=./routes.json
|
package/README.md
CHANGED
|
@@ -1,44 +1,26 @@
|
|
|
1
|
-
# KUKUY
|
|
1
|
+
# KUKUY - Balanceador de Carga
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
KUKUY es un sistema de balanceo de carga backend desarrollado en Node.js que permite distribuir solicitudes entre múltiples servidores backend utilizando diferentes algoritmos de balanceo. El sistema incluye características avanzadas como soporte para hooks, filtros, rutas personalizadas y un panel de control web.
|
|
4
4
|
|
|
5
|
-
## Características
|
|
5
|
+
## Características Principales
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- Soporte para
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
- Panel de control web para monitoreo
|
|
16
|
-
|
|
17
|
-
## Instalación
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm install
|
|
21
|
-
```
|
|
7
|
+
- **Algoritmos de Balanceo**: Soporta algoritmos como Round Robin e IP Hash
|
|
8
|
+
- **Soporte para HTTPS/SSL**: Capacidad de manejar conexiones seguras
|
|
9
|
+
- **Panel de Control Web**: Interfaz gráfica para monitorear el estado del sistema
|
|
10
|
+
- **Sistema de Plugins**: Arquitectura extensible mediante plugins
|
|
11
|
+
- **Hooks y Filtros**: Capacidad para interceptar y modificar solicitudes/responses
|
|
12
|
+
- **Rutas Personalizadas**: Configuración flexible de rutas para diferentes grupos de servidores
|
|
13
|
+
- **Monitoreo en Tiempo Real**: Métricas detalladas sobre rendimiento y estado de servidores
|
|
14
|
+
- **Reintento Inteligente**: Reenvío automático de solicitudes a servidores alternativos en caso de fallo
|
|
22
15
|
|
|
23
16
|
## Configuración
|
|
24
17
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- `BALANCER_HTTP_PORT`: Puerto para conexiones HTTP (por defecto: 8080)
|
|
28
|
-
- `BALANCER_HTTPS_PORT`: Puerto para conexiones HTTPS (opcional)
|
|
29
|
-
- `CONFIG_FILE_PATH`: Ruta al archivo de configuración de servidores (por defecto: ./servers.json)
|
|
30
|
-
- `ROUTES_FILE_PATH`: Ruta al archivo de configuración de rutas (por defecto: ./routes.json)
|
|
31
|
-
- `LOAD_BALANCING_ALGORITHM`: Algoritmo de balanceo a usar ('roundrobin' o 'iphash') (por defecto: 'roundrobin')
|
|
32
|
-
- `SSL_CERT_PATH`: Ruta al certificado SSL (requerido para HTTPS)
|
|
33
|
-
- `SSL_KEY_PATH`: Ruta a la llave privada SSL (requerido para HTTPS)
|
|
34
|
-
- `HEALTH_CHECK_INTERVAL`: Intervalo para verificación de salud en ms (por defecto: 30000)
|
|
35
|
-
- `LOG_LEVEL`: Nivel de logging (info, warn, error, debug) (por defecto: info)
|
|
36
|
-
- `LOG_FILE_PATH`: Ruta al archivo de logs (por defecto: ./balancer.log)
|
|
18
|
+
### Archivos de Configuración
|
|
37
19
|
|
|
38
|
-
|
|
20
|
+
El sistema utiliza varios archivos de configuración:
|
|
39
21
|
|
|
40
|
-
|
|
41
|
-
Define los servidores backend:
|
|
22
|
+
#### `servers.json`
|
|
23
|
+
Define los servidores backend a los que se distribuirán las solicitudes:
|
|
42
24
|
|
|
43
25
|
```json
|
|
44
26
|
{
|
|
@@ -46,21 +28,24 @@ Define los servidores backend:
|
|
|
46
28
|
{
|
|
47
29
|
"url": "http://localhost:3001",
|
|
48
30
|
"weight": 1,
|
|
49
|
-
"tags": ["api"]
|
|
50
|
-
"active": true
|
|
31
|
+
"tags": ["api"]
|
|
51
32
|
},
|
|
52
33
|
{
|
|
53
34
|
"url": "http://localhost:3002",
|
|
54
35
|
"weight": 1,
|
|
55
|
-
"tags": ["api"]
|
|
56
|
-
|
|
36
|
+
"tags": ["api"]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"url": "http://localhost:3003",
|
|
40
|
+
"weight": 1,
|
|
41
|
+
"tags": ["web"]
|
|
57
42
|
}
|
|
58
43
|
]
|
|
59
44
|
}
|
|
60
45
|
```
|
|
61
46
|
|
|
62
|
-
|
|
63
|
-
Define las
|
|
47
|
+
#### `routes.json`
|
|
48
|
+
Define las rutas y a qué grupo de servidores deben dirigirse:
|
|
64
49
|
|
|
65
50
|
```json
|
|
66
51
|
{
|
|
@@ -79,173 +64,124 @@ Define las reglas de enrutamiento para dirigir solicitudes específicas a grupos
|
|
|
79
64
|
}
|
|
80
65
|
```
|
|
81
66
|
|
|
82
|
-
|
|
83
|
-
- Las rutas definen patrones de URL (usando comodín `*`) y métodos HTTP permitidos
|
|
84
|
-
- El campo `target` especifica la etiqueta de servidores backend a los que se dirigirá la solicitud
|
|
85
|
-
- Por ejemplo, todas las solicitudes que empiezan con `/api/` se enviarán solo a servidores que tengan la etiqueta "api"
|
|
86
|
-
- Las solicitudes que no coincidan con ninguna ruta específica se distribuirán entre todos los servidores disponibles
|
|
87
|
-
|
|
88
|
-
## Uso
|
|
67
|
+
### Variables de Entorno
|
|
89
68
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
69
|
+
- `LOAD_BALANCING_ALGORITHM`: Algoritmo de balanceo ('roundrobin' o 'iphash')
|
|
70
|
+
- `BALANCER_HTTP_PORT`: Puerto HTTP del balanceador (por defecto 8080)
|
|
71
|
+
- `BALANCER_HTTPS_PORT`: Puerto HTTPS del balanceador
|
|
72
|
+
- `CONFIG_FILE_PATH`: Ruta al archivo de configuración de servidores
|
|
73
|
+
- `ROUTES_FILE_PATH`: Ruta al archivo de configuración de rutas
|
|
74
|
+
- `SSL_CERT_PATH`: Ruta al certificado SSL
|
|
75
|
+
- `SSL_KEY_PATH`: Ruta a la llave privada SSL
|
|
76
|
+
- `DASHBOARD_PORT`: Puerto del panel de control web (por defecto 8082)
|
|
77
|
+
- `WEBSOCKET_PORT`: Puerto del servidor WebSocket (por defecto 8083)
|
|
78
|
+
- `HEALTH_CHECK_INTERVAL`: Intervalo de verificación de salud de servidores
|
|
79
|
+
- `LOG_LEVEL`: Nivel de logging (por defecto 'info')
|
|
94
80
|
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
npm run dev
|
|
98
|
-
```
|
|
81
|
+
## Algoritmos de Balanceo
|
|
99
82
|
|
|
100
|
-
###
|
|
101
|
-
|
|
102
|
-
BALANCER_HTTP_PORT=9090 BALANCER_HTTPS_PORT=9443 CONFIG_FILE_PATH=./my-servers.json npm start
|
|
103
|
-
```
|
|
83
|
+
### Round Robin
|
|
84
|
+
Distribuye las solicitudes de forma equitativa entre todos los servidores disponibles, ciclando secuencialmente.
|
|
104
85
|
|
|
105
|
-
###
|
|
106
|
-
|
|
107
|
-
# Usar algoritmo RoundRobin (predeterminado)
|
|
108
|
-
LOAD_BALANCING_ALGORITHM=roundrobin npm start
|
|
86
|
+
### IP Hash
|
|
87
|
+
Utiliza la dirección IP del cliente para determinar a qué servidor se enviará la solicitud, asegurando que las solicitudes del mismo cliente siempre vayan al mismo servidor.
|
|
109
88
|
|
|
110
|
-
|
|
111
|
-
LOAD_BALANCING_ALGORITHM=iphash npm start
|
|
112
|
-
```
|
|
89
|
+
## Scripts de Inicio
|
|
113
90
|
|
|
114
|
-
|
|
91
|
+
El proyecto incluye scripts preconfigurados para iniciar el balanceador:
|
|
115
92
|
|
|
116
|
-
|
|
93
|
+
### `start-roundrobin.sh`
|
|
94
|
+
Inicia el balanceador con el algoritmo Round Robin:
|
|
117
95
|
```bash
|
|
118
96
|
./start-roundrobin.sh
|
|
119
97
|
```
|
|
120
98
|
|
|
121
|
-
|
|
99
|
+
### `start-iphash.sh`
|
|
100
|
+
Inicia el balanceador con el algoritmo IP Hash:
|
|
122
101
|
```bash
|
|
123
102
|
./start-iphash.sh
|
|
124
103
|
```
|
|
125
104
|
|
|
126
|
-
|
|
105
|
+
### `start-ssl.sh` y `start-ssl-config.sh`
|
|
106
|
+
Scripts para iniciar el balanceador con soporte SSL/TLS.
|
|
127
107
|
|
|
128
|
-
|
|
108
|
+
## Panel de Control Web
|
|
129
109
|
|
|
130
|
-
|
|
110
|
+
KUKUY incluye un panel de control web accesible en `http://localhost:8082` (por defecto) que muestra:
|
|
131
111
|
|
|
132
|
-
|
|
133
|
-
-
|
|
134
|
-
-
|
|
135
|
-
-
|
|
136
|
-
-
|
|
112
|
+
- Estado general del sistema
|
|
113
|
+
- Métricas de rendimiento (RPS, tiempo de respuesta promedio)
|
|
114
|
+
- Estado de los servidores backend
|
|
115
|
+
- Información sobre el algoritmo de balanceo actual
|
|
116
|
+
- Gráficos de uso reciente
|
|
137
117
|
|
|
138
|
-
|
|
139
|
-
```json
|
|
140
|
-
{
|
|
141
|
-
"serverStats": {
|
|
142
|
-
"1": {
|
|
143
|
-
"id": 1,
|
|
144
|
-
"totalRequests": 10,
|
|
145
|
-
"successfulRequests": 10,
|
|
146
|
-
"failedRequests": 0,
|
|
147
|
-
"totalResponseTime": 1250,
|
|
148
|
-
"minResponseTime": 5,
|
|
149
|
-
"maxResponseTime": 346,
|
|
150
|
-
"avgResponseTime": 125,
|
|
151
|
-
"responseCodes": {"200": 10},
|
|
152
|
-
"lastActive": 1769298297602,
|
|
153
|
-
"responseTimes": [346, 7, 7, 12, 45, 67, 89, 102, 115, 120]
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
## Hooks Disponibles
|
|
160
|
-
|
|
161
|
-
- `onRequestReceived`: Se ejecuta cuando se recibe una solicitud
|
|
162
|
-
- `onServerSelected`: Se ejecuta después de seleccionar un servidor backend
|
|
163
|
-
- `onResponseSent`: Se ejecuta cuando se envía la respuesta al cliente
|
|
164
|
-
- `onServerError`: Se ejecuta cuando ocurre un error con un servidor backend
|
|
165
|
-
|
|
166
|
-
## Filtros Disponibles
|
|
167
|
-
|
|
168
|
-
- `AuthenticationFilter`: Verificación de autenticación
|
|
169
|
-
- `RateLimitFilter`: Control de límite de peticiones
|
|
170
|
-
- `LoggingFilter`: Registro de solicitudes
|
|
171
|
-
- `CachingFilter`: Caché de respuestas
|
|
172
|
-
|
|
173
|
-
## Componentes Implementados
|
|
118
|
+
## Sistema de Plugins
|
|
174
119
|
|
|
175
|
-
|
|
176
|
-
- `Balancer.js`: Punto de entrada principal del sistema
|
|
177
|
-
- `ServerPool.js`: Gestión del conjunto de servidores backend
|
|
178
|
-
- `RequestHandler.js`: Manejo de solicitudes entrantes (integrado en Balancer.js)
|
|
120
|
+
La arquitectura de KUKUY permite extender su funcionalidad mediante plugins. Los plugins se colocan en el directorio `kukuy-plugins/` y deben incluir un archivo `manifest.json` con la configuración del plugin.
|
|
179
121
|
|
|
180
|
-
###
|
|
181
|
-
- `LoadBalancingAlgorithm.js`: Interfaz base para algoritmos de balanceo
|
|
182
|
-
- `RoundRobinAlgorithm.js`: Implementación del algoritmo RoundRobin como plugin
|
|
183
|
-
- `IPHashAlgorithm.js`: Implementación del algoritmo IPHash como plugin con asociación persistente IP-servidor
|
|
184
|
-
- `AlgorithmManager.js`: Gestor de algoritmos de balanceo con selección dinámica
|
|
122
|
+
### Estructura de un Plugin
|
|
185
123
|
|
|
186
|
-
|
|
187
|
-
- `ConfigManager.js`: Lee y procesa variables de entorno
|
|
188
|
-
- `RouteLoader.js`: Carga rutas y paths desde archivos de configuración
|
|
124
|
+
Un plugin típico incluye:
|
|
189
125
|
|
|
190
|
-
|
|
191
|
-
- `
|
|
192
|
-
- `HttpsBalancer.js`: Manejo de conexiones HTTPS
|
|
126
|
+
- `manifest.json`: Metadatos del plugin
|
|
127
|
+
- `index.js`: Código principal del plugin con funciones `init()` y `deinit()`
|
|
193
128
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
129
|
+
Ejemplo de `manifest.json`:
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"name": "Nombre del Plugin",
|
|
133
|
+
"version": "1.0.0",
|
|
134
|
+
"description": "Descripción del plugin",
|
|
135
|
+
"author": "Autor",
|
|
136
|
+
"main": "index.js",
|
|
137
|
+
"kukuyVersion": "^1.6.0",
|
|
138
|
+
"hooks": ["onRequestReceived", "onResponseSent"],
|
|
139
|
+
"filters": ["request_processing"],
|
|
140
|
+
"enabled": true
|
|
141
|
+
}
|
|
142
|
+
```
|
|
205
143
|
|
|
206
|
-
|
|
207
|
-
- **Hot Reload de Configuración**: Actualización de configuración sin reinicio (requiere implementación de listeners de cambio de archivos)
|
|
208
|
-
- **API REST para Gestión de Servidores**: Endpoint para añadir/eliminar servidores dinámicamente
|
|
209
|
-
- **Sistema de Alertas**: Notificaciones cuando servidores caen o se recuperan
|
|
210
|
-
- **Soporte para WebSocket**: Balanceo de conexiones WebSocket
|
|
211
|
-
- **Compresión de Respuestas**: Soporte para Gzip/Brotli
|
|
212
|
-
- **Persistencia de Sesión**: Sticky sessions basadas en cookies o IP
|
|
144
|
+
## Hooks y Filtros
|
|
213
145
|
|
|
214
|
-
###
|
|
215
|
-
|
|
216
|
-
-
|
|
217
|
-
-
|
|
146
|
+
### Hooks
|
|
147
|
+
Permiten ejecutar código en puntos específicos del ciclo de vida de una solicitud:
|
|
148
|
+
- `onRequestReceived`: Cuando se recibe una solicitud
|
|
149
|
+
- `onServerSelected`: Después de seleccionar un servidor destino
|
|
150
|
+
- `onResponseSent`: Antes de enviar la respuesta al cliente
|
|
151
|
+
- `onServerError`: Cuando ocurre un error con un servidor backend
|
|
218
152
|
|
|
219
|
-
|
|
153
|
+
### Filtros
|
|
154
|
+
Permiten interceptar y potencialmente modificar o bloquear solicitudes antes de que sean procesadas:
|
|
155
|
+
- Se pueden aplicar filtros de solicitud (`request`)
|
|
156
|
+
- Permiten implementar lógica de seguridad, autenticación, etc.
|
|
220
157
|
|
|
221
|
-
|
|
222
|
-
El proyecto incluye un script de prueba de estrés:
|
|
223
|
-
```bash
|
|
224
|
-
DURATION_SECONDS=30 CONCURRENT_REQUESTS=20 node stress-test.js
|
|
225
|
-
```
|
|
158
|
+
## Seguridad
|
|
226
159
|
|
|
227
|
-
|
|
160
|
+
- El sistema incluye mecanismos para marcar servidores como fallidos temporalmente
|
|
161
|
+
- Implementa reintento inteligente hacia servidores alternativos
|
|
162
|
+
- Permite configurar límites de intentos fallidos antes de excluir un servidor
|
|
228
163
|
|
|
229
|
-
|
|
230
|
-
El dashboard no refleja en tiempo real cuando servidores se vuelven offline o se levantan después de iniciar el balanceador. La información de estado de los servidores puede no actualizar inmediatamente cuando un servidor backend cambia de estado.
|
|
164
|
+
## Monitoreo y Métricas
|
|
231
165
|
|
|
232
|
-
|
|
166
|
+
KUKUY proporciona métricas detalladas sobre:
|
|
167
|
+
- Solicitudes totales procesadas
|
|
168
|
+
- RPS (Solicitudes por segundo) acumulado e instantáneo
|
|
169
|
+
- Tiempo de respuesta promedio
|
|
170
|
+
- Tasa de éxito
|
|
171
|
+
- Estado de salud de los servidores
|
|
172
|
+
- Uso de recursos del sistema (CPU, memoria)
|
|
233
173
|
|
|
234
174
|
## Licencia
|
|
235
175
|
|
|
236
|
-
Este proyecto está licenciado bajo la Licencia
|
|
176
|
+
Este proyecto está licenciado bajo la Licencia GPL-3.0 o posterior.
|
|
237
177
|
|
|
238
|
-
|
|
178
|
+
## Autor
|
|
239
179
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
180
|
+
Benjamín Sánchez Cárdenas
|
|
181
|
+
Email de contacto: bytedogssyndicate@gmail.com
|
|
182
|
+
Página web oficial: https://bsanchez.unaux.com/
|
|
183
|
+
Repositorio oficial: https://gitlab.com/bytedogssyndicate1/kukuy
|
|
244
184
|
|
|
245
|
-
|
|
246
|
-
SIN NINGUNA GARANTÍA; ni siquiera la garantía implícita de
|
|
247
|
-
COMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR.
|
|
248
|
-
Consulte la Licencia Pública General GNU para obtener más detalles.
|
|
185
|
+
## Contribuciones
|
|
249
186
|
|
|
250
|
-
|
|
251
|
-
junto con este programa. Si no, consulte <https://www.gnu.org/licenses/>.
|
|
187
|
+
Las contribuciones son bienvenidas. Por favor, abre un issue o pull request para discutir cambios propuestos.
|
package/balancer.log
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
{"timestamp":"2026-01-30T19:04:05.202Z","level":"INFO","message":"Servidor ONLINE - ID: 1, URL: http://localhost:3434","eventType":"target_online","serverId":1,"serverUrl":"http://localhost:3434","request":{"url":"/track/insertSiteFlow","method":"POST","responseTime":631,"statusCode":200}}
|
|
2
|
+
{"timestamp":"2026-01-30T19:04:34.272Z","level":"INFO","message":"Servidor ONLINE - ID: 1, URL: http://localhost:3434","eventType":"target_online","serverId":1,"serverUrl":"http://localhost:3434","request":{"url":"/track/insertSiteFlow","method":"POST","responseTime":56,"statusCode":200}}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
|
2
|
+
MIIDtzCCAp+gAwIBAgIUFTU+RfyHp2GmFigOSZ9AiN8SGLcwDQYJKoZIhvcNAQEL
|
|
3
|
+
BQAwazELMAkGA1UEBhMCRVMxDzANBgNVBAgMBk1hZHJpZDEPMA0GA1UEBwwGTWFk
|
|
4
|
+
cmlkMQ4wDAYDVQQKDAVLdWt1eTEWMBQGA1UECwwNSVQgRGVwYXJ0bWVudDESMBAG
|
|
5
|
+
A1UEAwwJbG9jYWxob3N0MB4XDTI2MDEyNjAxNTU1NFoXDTI3MDEyNjAxNTU1NFow
|
|
6
|
+
azELMAkGA1UEBhMCRVMxDzANBgNVBAgMBk1hZHJpZDEPMA0GA1UEBwwGTWFkcmlk
|
|
7
|
+
MQ4wDAYDVQQKDAVLdWt1eTEWMBQGA1UECwwNSVQgRGVwYXJ0bWVudDESMBAGA1UE
|
|
8
|
+
AwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlN3F
|
|
9
|
+
rAiKzKOIybQsmGIF+sBmfgkqsC/jq3EBsOnIDXG2Kz0AVLNCD1nxTmYB06x7TN7V
|
|
10
|
+
xCSXiaGJEAW2v2+CLOpiFtO9S9hnxsoENN3DI/ZNYVBD5QbPFdkyTUw31iq8Vdhp
|
|
11
|
+
tkrxwnY7q7S/Ss1BEKxL/y0f4bSD9bXAYbTJRFlx5bv8KE0+Opr3EywGmyd9Fwwq
|
|
12
|
+
Zf4+z19kc4/ILmguzrMTZ9MblzKN5VAxoQ+h5SzKY/pgIPTX9Y25ciKwlN8nPrYs
|
|
13
|
+
32CfFVqyH1sWY+hz8nhPIqJ++R12cofTyjBkfUoo7hE87wsIITmttxA9gJfd9k2j
|
|
14
|
+
jy6ebm40SGaHXjU7twIDAQABo1MwUTAdBgNVHQ4EFgQUYK1YQGMWkT9TpbPspqtu
|
|
15
|
+
tWzX3EMwHwYDVR0jBBgwFoAUYK1YQGMWkT9TpbPspqtutWzX3EMwDwYDVR0TAQH/
|
|
16
|
+
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEADQWlR94ZUUSv+nYzpvhyonnxDoy+
|
|
17
|
+
YU4MATcisHc6HnbLUdwX95dSzIFLg/aurqcadWTL6q2RQusUpfpNdVPJXvXUXz/W
|
|
18
|
+
ebk1Q97qcz8jFp9hbZxb93mrmJE0JccMU36WZPVM8J9K8p11JABn+sJRQFIAOauU
|
|
19
|
+
C7ETVs84+b3JNLGH9Y3cJpB6Jm7DntFXZmp6Ehe8On4SwqIRfN11CKQs7SqcHXts
|
|
20
|
+
X6tgXisc7HskSbXXG5oSHKz+uwngH2V85RH/pKgly80IRT3FbPzFRBdSCDk6B4PM
|
|
21
|
+
Bqow/h9NX65Vd5aRFpsmje4eqrO2g0YQsPmpVAndIstn+HlW5YyLAb5dmA==
|
|
22
|
+
-----END CERTIFICATE-----
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
-----BEGIN PRIVATE KEY-----
|
|
2
|
+
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCU3cWsCIrMo4jJ
|
|
3
|
+
tCyYYgX6wGZ+CSqwL+OrcQGw6cgNcbYrPQBUs0IPWfFOZgHTrHtM3tXEJJeJoYkQ
|
|
4
|
+
Bba/b4Is6mIW071L2GfGygQ03cMj9k1hUEPlBs8V2TJNTDfWKrxV2Gm2SvHCdjur
|
|
5
|
+
tL9KzUEQrEv/LR/htIP1tcBhtMlEWXHlu/woTT46mvcTLAabJ30XDCpl/j7PX2Rz
|
|
6
|
+
j8guaC7OsxNn0xuXMo3lUDGhD6HlLMpj+mAg9Nf1jblyIrCU3yc+tizfYJ8VWrIf
|
|
7
|
+
WxZj6HPyeE8ion75HXZyh9PKMGR9SijuETzvCwghOa23ED2Al932TaOPLp5ubjRI
|
|
8
|
+
ZodeNTu3AgMBAAECggEAIXLhNwHmWgvGsPeca5Le4BQ6E0ixAEyKXduy8xLcYfTy
|
|
9
|
+
Zy26NM3gYn2lpCV0dKDVRZTuODe2mvSiTOjTwpjmCXySlKl356JU0wxSPKS1c4+k
|
|
10
|
+
nGCCGORaRID8dfTRuPv6PFm3iv+06apSRwcCUmbjH0FvhAMaHkdGvT9c3jdWX9ZX
|
|
11
|
+
YpHtnQQzWQSdNByT6ELqUCD2lw9AtzRSdvMDEZ/H7WfepcJ8jNNAzLkNQIuezDR1
|
|
12
|
+
ciFA5dDhT8vOkEBV1LiQz0uUscsyefhDG1rUmFJxUng9IW2qNFEKxBfiWdZIGEK3
|
|
13
|
+
PInBm4QpOLHh1q6+XK2yeRSnw8uMfgPlDQgr5cGDYQKBgQDKLD01Letd0URs0INL
|
|
14
|
+
LRLox/k8GrCKEDXl+y7EvbWnLriDck4I+fkuQKenxQdVCBCOKGRgm92j3Y8vB+9I
|
|
15
|
+
QU8lIzohgAUt5GAm+7ZNdwbTX3hYmUmIFXdZEvIBZ61Xw+ghwSWh44Af5S8w4xoi
|
|
16
|
+
C5ewa4iBvSApOHzs6Q6/Tf8WYQKBgQC8gEATZNmiXH3ITYdGVmEY5uzqRyJIXt3y
|
|
17
|
+
BbfFooZc31daUx4HDnjgzdY8I5cr3JfNy1HvpXcLMWH79nRbEcwvaiKkqkvaGxHW
|
|
18
|
+
e6NTTkU46P4lAwtzsfM7eQrtRnfJGLUF7ZQzc/W05BkdyLq2Fmrox8Mt01rZs9Yo
|
|
19
|
+
R+4tv5LZFwKBgQCJ9uSSDNMIg81RAH4IaCr2Rbj0ZjZBEUzms6G3yspS21Q5B2Dv
|
|
20
|
+
ST7dbGu81nzpbwZ1LGVLdDItJ/4VFzIYOdE7w61gvQ9LwQRItg8zD93NkuH6fCis
|
|
21
|
+
wBFg7MfPY6PsN5mKp1b6AdkmauzoTKJBx21tjARsnNZ8qrq9pVFWBXDlIQKBgQC1
|
|
22
|
+
bOa/A9DoEQdLEzuAukCn/BLIhgB8ETqi51fyEzQpDRkBKYB8IDS9gb+RkFu+bol5
|
|
23
|
+
HBjXg7UpA7WgEZv5zw5sEEYZoIJzAJzRh5wx4OKFHNMHAoAyMXK+qgiXSLyfw3Tv
|
|
24
|
+
qLN8Nj6lhOibnwf9m2P4edPkNkl5wTn8+QZH59vJrwKBgDi7kLHz+fLxM6BYQ92F
|
|
25
|
+
mRgxHoY1Cj0jpPEGx+9A7e8f2zQUSb9nUU0et0NHmiGmgkUTqVwy7lWGFSXjvoaz
|
|
26
|
+
Vm1UrDskAbngwmSHpPDeBZTOHHR9PRyPWdJqUzJjk7boQK9gK65BeYLkY9klJFIN
|
|
27
|
+
bWZG2VQiV6rOcc/8WWgZtlrG
|
|
28
|
+
-----END PRIVATE KEY-----
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Sistema de Plugins para Kukuy
|
|
2
|
+
|
|
3
|
+
## Introducción
|
|
4
|
+
|
|
5
|
+
Kukuy incluye un sistema de plugins que permite extender su funcionalidad sin modificar el código base. Los plugins se almacenan en el directorio `kukuy-plugins/` y se cargan automáticamente al iniciar Kukuy.
|
|
6
|
+
|
|
7
|
+
## Estructura de un Plugin
|
|
8
|
+
|
|
9
|
+
Cada plugin debe tener la siguiente estructura:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
kukuy-plugins/
|
|
13
|
+
└── nombre-del-plugin/
|
|
14
|
+
├── manifest.json
|
|
15
|
+
└── index.js
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Manifest
|
|
19
|
+
|
|
20
|
+
El archivo `manifest.json` debe contener:
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"name": "Nombre del Plugin",
|
|
25
|
+
"version": "1.0.0",
|
|
26
|
+
"description": "Descripción del plugin",
|
|
27
|
+
"author": "Autor del plugin",
|
|
28
|
+
"main": "index.js",
|
|
29
|
+
"kukuyVersion": "^1.6.0",
|
|
30
|
+
"hooks": ["onRequestReceived", "onResponseSent"],
|
|
31
|
+
"filters": ["request_processing"],
|
|
32
|
+
"enabled": true
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Campos obligatorios:
|
|
37
|
+
- `name`: Nombre del plugin
|
|
38
|
+
- `version`: Versión del plugin
|
|
39
|
+
- `description`: Descripción del plugin
|
|
40
|
+
- `main`: Archivo principal del plugin
|
|
41
|
+
- `enabled`: Si el plugin está habilitado o no
|
|
42
|
+
|
|
43
|
+
Campos opcionales:
|
|
44
|
+
- `author`: Autor del plugin
|
|
45
|
+
- `kukuyVersion`: Versión de Kukuy requerida
|
|
46
|
+
- `hooks`: Lista de hooks que el plugin usa
|
|
47
|
+
- `filters`: Lista de filtros que el plugin usa
|
|
48
|
+
- `dependencies`: Dependencias del plugin
|
|
49
|
+
|
|
50
|
+
## Archivo Principal
|
|
51
|
+
|
|
52
|
+
El archivo principal (por defecto `index.js`) debe exportar las funciones:
|
|
53
|
+
|
|
54
|
+
- `init(balancer)`: Se llama cuando se carga el plugin
|
|
55
|
+
- `deinit(balancer)`: Se llama cuando se descarga el plugin (opcional)
|
|
56
|
+
|
|
57
|
+
## API de Extensión
|
|
58
|
+
|
|
59
|
+
Dentro del plugin, puedes usar la API de extensión para registrar filtros y hooks:
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
async function init(balancer) {
|
|
63
|
+
const extension = balancer.getPostStartupExtension();
|
|
64
|
+
|
|
65
|
+
// Registrar un filtro
|
|
66
|
+
extension.registerFilter('request_processing', async (data) => {
|
|
67
|
+
// Lógica del filtro
|
|
68
|
+
return { allowed: true };
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Registrar un hook
|
|
72
|
+
extension.registerHook('onRequestReceived', async ({ req, res }) => {
|
|
73
|
+
// Lógica del hook
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Hooks Disponibles
|
|
79
|
+
|
|
80
|
+
- `onRequestReceived`: Se ejecuta cuando se recibe una solicitud
|
|
81
|
+
- `onServerSelected`: Se ejecuta después de seleccionar el servidor
|
|
82
|
+
- `onResponseSent`: Se ejecuta antes de enviar la respuesta
|
|
83
|
+
- `onServerError`: Se ejecuta cuando ocurre un error
|
|
84
|
+
|
|
85
|
+
## Filtros Disponibles
|
|
86
|
+
|
|
87
|
+
- `request_processing`: Se aplica al procesamiento de solicitudes
|
|
88
|
+
|
|
89
|
+
## Variables de Entorno
|
|
90
|
+
|
|
91
|
+
- `PLUGINS_DIR`: Directorio donde buscar plugins (por defecto: `./kukuy-plugins`)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin de ejemplo para Kukuy
|
|
3
|
+
* Demuestra cómo crear un plugin que se carga automáticamente
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
async function init(balancer) {
|
|
7
|
+
console.log('Inicializando plugin de ejemplo...');
|
|
8
|
+
|
|
9
|
+
const extension = balancer.getPostStartupExtension();
|
|
10
|
+
|
|
11
|
+
// Registrar un filtro de ejemplo
|
|
12
|
+
extension.registerFilter('request_processing', async (data) => {
|
|
13
|
+
const { req, res } = data;
|
|
14
|
+
console.log(`Plugin: Procesando solicitud ${req.method} ${req.url}`);
|
|
15
|
+
|
|
16
|
+
// Agregar un header personalizado
|
|
17
|
+
req.headers['x-plugin-example'] = 'activated';
|
|
18
|
+
|
|
19
|
+
return { allowed: true };
|
|
20
|
+
}, 5);
|
|
21
|
+
|
|
22
|
+
// Registrar un hook para cuando se recibe una solicitud
|
|
23
|
+
extension.registerHook('onRequestReceived', async ({ req, res }) => {
|
|
24
|
+
console.log(`Plugin: Solicitud recibida - ${req.method} ${req.url}`);
|
|
25
|
+
}, 5);
|
|
26
|
+
|
|
27
|
+
// Registrar un hook para cuando se envía la respuesta
|
|
28
|
+
extension.registerHook('onResponseSent', async ({ req, res, serverRes, responseTime }) => {
|
|
29
|
+
console.log(`Plugin: Respuesta enviada para ${req.url} en ${responseTime}ms`);
|
|
30
|
+
}, 5);
|
|
31
|
+
|
|
32
|
+
console.log('Plugin de ejemplo inicializado correctamente');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function deinit(balancer) {
|
|
36
|
+
console.log('Desactivando plugin de ejemplo...');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = { init, deinit };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Plugin de Ejemplo",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Plugin de ejemplo para demostrar la arquitectura de plugins",
|
|
5
|
+
"author": "Desarrollador",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"kukuyVersion": "^1.6.0",
|
|
8
|
+
"hooks": ["onRequestReceived", "onResponseSent"],
|
|
9
|
+
"filters": ["request_processing"],
|
|
10
|
+
"enabled": true
|
|
11
|
+
}
|
package/kukuy.js
CHANGED
|
@@ -1,23 +1,69 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { Balancer } = require('./src/core/Balancer');
|
|
4
|
+
const packageJson = require('./package.json');
|
|
5
|
+
|
|
6
|
+
// Medir tiempo de inicio
|
|
7
|
+
const startTime = Date.now();
|
|
8
|
+
const startMemory = process.memoryUsage();
|
|
4
9
|
|
|
5
10
|
// Iniciar el balanceador
|
|
6
11
|
const balancer = new Balancer();
|
|
7
12
|
balancer.start();
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
// Calcular tiempo de inicio y uso de memoria
|
|
15
|
+
const startupTime = Date.now() - startTime;
|
|
16
|
+
const endMemory = process.memoryUsage();
|
|
17
|
+
const memoryUsed = endMemory.heapUsed - startMemory.heapUsed;
|
|
18
|
+
|
|
19
|
+
// Colores para la consola
|
|
20
|
+
const colors = {
|
|
21
|
+
reset: '\x1b[0m',
|
|
22
|
+
bright: '\x1b[1m',
|
|
23
|
+
dim: '\x1b[2m',
|
|
24
|
+
underscore: '\x1b[4m',
|
|
25
|
+
blink: '\x1b[5m',
|
|
26
|
+
reverse: '\x1b[7m',
|
|
27
|
+
hidden: '\x1b[8m',
|
|
28
|
+
|
|
29
|
+
fgBlack: '\x1b[30m',
|
|
30
|
+
fgRed: '\x1b[31m',
|
|
31
|
+
fgGreen: '\x1b[32m',
|
|
32
|
+
fgYellow: '\x1b[33m',
|
|
33
|
+
fgBlue: '\x1b[34m',
|
|
34
|
+
fgMagenta: '\x1b[35m',
|
|
35
|
+
fgCyan: '\x1b[36m',
|
|
36
|
+
fgWhite: '\x1b[37m',
|
|
37
|
+
|
|
38
|
+
bgBlack: '\x1b[40m',
|
|
39
|
+
bgRed: '\x1b[41m',
|
|
40
|
+
bgGreen: '\x1b[42m',
|
|
41
|
+
bgYellow: '\x1b[43m',
|
|
42
|
+
bgBlue: '\x1b[44m',
|
|
43
|
+
bgMagenta: '\x1b[45m',
|
|
44
|
+
bgCyan: '\x1b[46m',
|
|
45
|
+
bgWhite: '\x1b[47m'
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Mostrar información con colores
|
|
49
|
+
console.log(`${colors.fgYellow}${colors.bright}╔══════════════════════════════════════════════════════════════╗${colors.reset}`);
|
|
50
|
+
console.log(`${colors.fgYellow}${colors.bright}║ KUKUY BALANCEADOR ║${colors.reset}`);
|
|
51
|
+
console.log(`${colors.fgYellow}${colors.bright}╚══════════════════════════════════════════════════════════════╝${colors.reset}`);
|
|
52
|
+
console.log(`${colors.fgYellow}Versión:${colors.reset} ${colors.fgGreen}${colors.bright}${packageJson.version}${colors.reset}`);
|
|
53
|
+
console.log(`${colors.fgYellow}Tiempo de inicio:${colors.reset} ${colors.fgGreen}${colors.bright}${startupTime} ms${colors.reset}`);
|
|
54
|
+
console.log(`${colors.fgYellow}Memoria consumida:${colors.reset} ${colors.fgGreen}${colors.bright}${Math.round(memoryUsed / 1024 / 1024 * 100) / 100} MB${colors.reset}`);
|
|
55
|
+
console.log(`${colors.fgYellow}${colors.bright}Balanceador RoundRobin iniciado${colors.reset}`);
|
|
56
|
+
console.log(`${colors.fgBlue}Panel web disponible en: http://localhost:${process.env.DASHBOARD_PORT || 8082}${colors.reset}`);
|
|
11
57
|
|
|
12
58
|
// Manejar señales de interrupción
|
|
13
59
|
process.on('SIGINT', () => {
|
|
14
|
-
console.log(
|
|
60
|
+
console.log(`\n${colors.fgRed}Cerrando balanceador...${colors.reset}`);
|
|
15
61
|
balancer.stop();
|
|
16
62
|
process.exit(0);
|
|
17
63
|
});
|
|
18
64
|
|
|
19
65
|
process.on('SIGTERM', () => {
|
|
20
|
-
console.log(
|
|
66
|
+
console.log(`${colors.fgRed}Recibida señal SIGTERM, cerrando...${colors.reset}`);
|
|
21
67
|
balancer.stop();
|
|
22
68
|
process.exit(0);
|
|
23
|
-
});
|
|
69
|
+
});
|