此内容没有您所选择的语言版本。

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 remote name-service.
name-service
name-service receives the request from greeting-service. The web client interface contains a toggle button that you can click to simulate the availability or failure of the remote name-service. If the toggle button is currently set to on, name-service sends a response to complete the greeting. However, if the toggle button is currently set to off, 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 remote name-service as part of processing the client request. The call to the /api/name endpoint is wrapped in a circuit breaker object. If the remote name-service is currently available, the /api/greeting endpoint sends a greeting to the client. However, if the remote name-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 to open, the circuit breaker is currently preventing requests from reaching the failed service. If this is set to closed, 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;
Copy to Clipboard Toggle word wrap

3.3. Example name-service

name-service exposes the following endpoints:

  • The /api/name endpoint receives a call from greeting-service. If name-service is currently available, the /api/name endpoint sends a World! response to complete the greeting. However, if name-service is currently unavailable, the /api/name endpoint sends a Name service down error with an HTTP status code of 500.
  • 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;
Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat