Ce contenu n'est pas disponible dans la langue sélectionnée.
Chapter 3. Example application using the circuit breaker add-on
You can use the circuit breaker add-on to implement a circuit breaker pattern in your Node.js applications. This example shows how to use the circuit breaker add-on to report the failure of a remote service and to limit access to the failed service until it becomes available to handle requests.
3.1. Overview of the example application
This example application consists of two microservices:
- greeting-service
-
This is the entry point to the application. A web client calls
greeting-service
to request a greeting.greeting-service
then sends a request that is wrapped in a circuit breaker object to the remotename-service
. - name-service
-
name-service
receives the request fromgreeting-service
. The web client interface contains a toggle button that you can click to simulate the availability or failure of the remotename-service
. If the toggle button is currently set toon
,name-service
sends a response to complete the greeting. However, if the toggle button is currently set tooff
,name-service
sends an error to indicate that the service is currently unavailable.
3.2. Example greeting-service
greeting-service
imports the circuit breaker add-on. greeting-service
protects calls to the remote name-service
by wrapping these calls in a circuit breaker object.
greeting-service
exposes the following endpoints:
-
The
/api/greeting
endpoint receives a call from the web client that requests a greeting. The/api/greeting
endpoint sends a call to the/api/name
endpoint in the remotename-service
as part of processing the client request. The call to the/api/name
endpoint is wrapped in a circuit breaker object. If the remotename-service
is currently available, the/api/greeting
endpoint sends a greeting to the client. However, if the remotename-service
is currently unavailable, the/api/greeting
endpoint sends an error response to the client. -
The
/api/cb-state
endpoint returns the current state of the circuit breaker. If this is set toopen
, the circuit breaker is currently preventing requests from reaching the failed service. If this is set toclosed
, the circuit breaker is currently allowing requests to reach the service.
The following code example shows how to develop greeting-service
:
'use strict'; const path = require('path'); const http = require('http'); const express = require('express'); const bodyParser = require('body-parser'); // Import the circuit breaker add-on const Opossum = require('@redhat/opossum'); const probe = require('kube-probe'); const nameService = require('./lib/name-service-client'); const app = express(); const server = http.createServer(app); // Add basic health check endpoints probe(app); const nameServiceHost = process.env.NAME_SERVICE_HOST || 'http://nodejs-circuit-breaker-redhat-name:8080'; // Set some circuit breaker options const circuitOptions = { timeout: 3000, // If name service takes longer than 0.3 seconds, // trigger a failure errorThresholdPercentage: 50, // When 50% of requests fail, // trip the circuit resetTimeout: 10000 // After 10 seconds, try again. }; // Create a new circuit breaker instance and pass the remote nameService // as its first parameter const circuit = new Opossum(nameService, circuitOptions); // Create the app with an initial websocket endpoint require('./lib/web-socket')(server, circuit); // Serve index.html from the file system app.use(express.static(path.join(__dirname, 'public'))); // Expose the license.html at http[s]://[host]:[port]/licences/licenses.html app.use('/licenses', express.static(path.join(__dirname, 'licenses'))); // Send and receive json app.use(bodyParser.json()); // Greeting API app.get('/api/greeting', (request, response) => { // Use the circuit breaker’s fire method to execute the call // to the name service circuit.fire(`${nameServiceHost}/api/name`).then(name => { response.send({ content: `Hello, ${name}`, time: new Date() }); }).catch(console.error); }); // Circuit breaker state API app.get('/api/cb-state', (request, response) => { response.send({ state: circuit.opened ? 'open' : 'closed' }); }); app.get('/api/name-service-host', (request, response) => { response.send({ host: nameServiceHost }); }); module.exports = server;
3.3. Example name-service
name-service
exposes the following endpoints:
-
The
/api/name
endpoint receives a call fromgreeting-service
. Ifname-service
is currently available, the/api/name
endpoint sends aWorld!
response to complete the greeting. However, ifname-service
is currently unavailable, the/api/name
endpoint sends aName service down
error with an HTTP status code of500
. -
The
/api/state
endpoint controls the current behavior of the/api/name
endpoint. It determines whether the service sends a response or fails with an error message.
The following code example shows how to develop name-service
:
'use strict'; const path = require('path'); const http = require('http'); const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const probe = require('kube-probe'); const app = express(); const server = http.createServer(app); // Adds basic health-check endpoints probe(app); let isOn = true; const { update, sendMessage } = require('./lib/web-socket')(server, _ => isOn); // Send and receive json app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); // CORS support app.use(cors()); // Name service API app.get('/api/name', (request, response) => { if (isOn) { response.send('World!'); } else { response.status(500).send('Name service down'); } sendMessage(`${new Date()} ${isOn ? 'OK' : 'FAIL'}`); }); // Current state of service app.put('/api/state', (request, response) => { isOn = request.body.state === 'ok'; response.send({ state: isOn }); update(); }); app.get('/api/info', (request, response) => response.send({ state: isOn ? 'ok' : 'fail' })); // Expose the license.html at http[s]://[host]:[port]/licenses/licenses.html app.use('/licenses', express.static(path.join(__dirname, 'licenses'))); module.exports = server;
Additional resources
- For more information about deploying and running the example circuit breaker application, see the Node.js Runtime Guide.
- For more information about the member types that you can use with the circuit breaker add-on, see the Circuit Breaker Add-on 5.0.0 API Documentation.