One place for hosting & domains

      How To Create an HTTP Client with Core HTTP in Node.js


      The author selected the COVID-19 Relief Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      It’s common for a modern web application to communicate with other servers to accomplish a task. For example, a web app that allows you to purchase a book online may involve communication between a customer orders server, a book inventory server, and a payment server. In this design, the different services communicate via web APIs—standard formats that allow you to programmatically send and receive data. In a Node.js app, you can communicate with web APIs by making HTTP requests.

      Node.js comes bundled with an http and an https module. These modules have functions to create an HTTP server so that a Node.js program can respond to HTTP requests. They can also make HTTP requests to other servers. This key functionality equips Node.js programmers to create modern, API-driven web applications with Node.js. As it’s a core module, you do not need to install any libraries to use it.

      In this tutorial, you will use the https module to make HTTP requests to JSON Placeholder, a fake REST API for testing purposes. You will begin by making a GET request, the standard HTTP request to receive data. You will then look at ways to customize your request, such as by adding headers. Finally, you will make POST, PUT, and DELETE requests so that you can modify data in an external server.

      Prerequisites

      • This tutorial requires that you have Node.js installed. Once installed, you will be able to access the https module that’s used throughout the tutorial. This tutorial uses Node.js version 10.19.0. To install Node.js on macOS or Ubuntu 18.04, follow the steps in How To Install Node.js and Create a Local Development Environment on macOS or the Installing Using a PPA section of How To Install Node.js on Ubuntu 18.04.

      • The methods used to send HTTP requests have a Stream-based API. In Node.js, streams are instances of event emitters. The way in which you respond to data coming from a stream is the same as the way in which you respond to data from events. If you are curious, you can get more in-depth knowledge of event emitters by reading our Using Event Emitters in Node.js guide.

      Step 1 — Making a GET Request

      When you interact with an API, you typically make GET requests to retrieve data from web servers. In this step, you’ll look at two functions to make GET requests in Node.js. Your code will retrieve a JSON array of user profiles from a publicly accessible API.

      The https module has two functions to make GET requests—the get() function, which can only make GET requests, and the request() function, which makes other types of requests. You will begin by making a request with the get() function.

      Making Requests with get()

      HTTP requests using the get() function have this format:

      https.get(URL_String, Callback_Function) {
          Action
      }
      

      The first argument is a string with the endpoint you’re making the request to. The second argument is a callback function, which you use to handle the response.

      First, set up your coding environment. In your terminal, create a folder to store all your Node.js modules for this guide:

      Enter that folder:

      Create and open a new file in a text editor. This tutorial will use nano as it’s available in the terminal:

      • nano getRequestWithGet.js

      To make HTTP requests in Node.js, import the https module by adding the follow line:

      requests/getRequestWithGet.js

      const https = require('https');
      

      Note:: Node.js has an http and an https module. They have the same functions and behave in a similar manner, but https makes the requests through the Transport Layer Security (TLS/SSL). As the web servers you are using are available via HTTPS, you will use the https module. If you are making requests to and from URLs that only have HTTP, then you would use the http module.

      Now use the http object to make a GET request to the API to retrieve a list of users. You will use JSON Placeholder, a publicly available API for testing. This API does not keep a record of any changes you make in your requests. It simulates a real server, and returns mocked responses as long as you send a valid request.

      Write the following highlighted code in your text editor:

      requests/getRequestWithGet.js

      const https = require('https');
      
      let request = https.get('https://jsonplaceholder.typicode.com/users?_limit=2', (res) => { });
      

      As mentioned in the function signature, the get() function takes two parameters. The first is the API URL you are making the request to in string format and the second is a callback to handle the HTTP response. To read the data from your response, you have to add some code in the callback.

      HTTP responses come with a status code. A status code is a number that indicates how successful the response was. Status codes between 200 and 299 are positive responses, while codes between 400 and 599 are errors. You can learn more about status codes in our How To Troubleshoot Common HTTP Error Codes guide.

      For this request, a successful response would have a 200 status code. The first thing you’ll do in your callback will be to verify that the status code is what you expect. Add the following code to the callback function:

      requests/getRequestWithGet.js

      const https = require('https');
      
      let request = https.get('https://jsonplaceholder.typicode.com/users?_limit=2', (res) => {
        if (res.statusCode !== 200) {
          console.error(`Did not get an OK from the server. Code: ${res.statusCode}`);
          res.resume();
          return;
        }
      });
      

      The response object that’s available in the callback has a statusCode property that stores the status code. If the status code is not 200, you log an error to the console and exit.

      Note the line that has res.resume(). You included that line to improve performance. When making HTTP requests, Node.js will consume all the data that’s sent with the request. The res.resume() method tells Node.js to ignore the stream’s data. In turn, Node.js would typically discard the data more quickly than if it left it for garbage collection—a periodic process that frees an application’s memory.

      Now that you’ve captured error responses, add code to read the data. Node.js responses stream their data in chunks. The strategy for retrieving data will be to listen for when data comes from the response, collate all the chunks, and then parse the JSON so your application can use it.

      Modify the request callback to include this code:

      requests/getRequestWithGet.js

      const https = require('https');
      
      let request = https.get('https://jsonplaceholder.typicode.com/users?_limit=2', (res) => {
        if (res.statusCode !== 200) {
          console.error(`Did not get an OK from the server. Code: ${res.statusCode}`);
          res.resume();
          return;
        }
      
        let data="";
      
        res.on('data', (chunk) => {
          data += chunk;
        });
      
        res.on('close', () => {
          console.log('Retrieved all data');
          console.log(JSON.parse(data));
        });
      });
      

      You begin by creating a new variable data that’s an empty string. You can store data as an array of numbers representing byte data or a string. This tutorial uses the latter as it’s easier to convert a JSON string to a JavaScript object.

      After creating the data variable, you create an event listener. Node.js streams the data of an HTTP response in chunks. Therefore, when the response object emits a data event, you will take the data it received and add it to your data variable.

      When all the data from the server is received, Node.js emits a close event. At this point, you parse the JSON string stored in data and log the result to the console.

      Your Node.js module can now communicate with the JSON API and log the list of users, which will be a JSON array of three users. However, there’s one small improvement you can make first.

      This script will throw an error if you are unable to make a request. You may not be able to make a request if you lose your internet connection, for example. Add the following code to capture errors when you’re unable to send an HTTP request:

      requests/getRequestWithGet.js

      ...
        res.on('data', (chunk) => {
          data += chunk;
        });
      
        res.on('close', () => {
          console.log('Retrieved all data');
          console.log(JSON.parse(data));
        });
      
      });
      
      request.on('error', (err) => {
        console.error(`Encountered an error trying to make a request: ${err.message}`);
      });
      

      When a request is made but cannot be sent, the request object emits an error event. If an error event is emitted but not listened to, the Node.js program crashes. Therefore, to capture errors you add an event listener with the on() function and listen for error events. When you get an error, you log its message.

      That’s all the code for this file. Save and exit nano by pressing CTRL+X.

      Now execute this program with node:

      • node getRequestWithGet.js

      Your console will display this response:

      Output

      Retrieved all data [ { id: 1, name: 'Leanne Graham', username: 'Bret', email: 'Sincere@april.biz', address: { street: 'Kulas Light', suite: 'Apt. 556', city: 'Gwenborough', zipcode: '92998-3874', geo: [Object] }, phone: '1-770-736-8031 x56442', website: 'hildegard.org', company: { name: 'Romaguera-Crona', catchPhrase: 'Multi-layered client-server neural-net', bs: 'harness real-time e-markets' } }, { id: 2, name: 'Ervin Howell', username: 'Antonette', email: 'Shanna@melissa.tv', address: { street: 'Victor Plains', suite: 'Suite 879', city: 'Wisokyburgh', zipcode: '90566-7771', geo: [Object] }, phone: '010-692-6593 x09125', website: 'anastasia.net', company: { name: 'Deckow-Crist', catchPhrase: 'Proactive didactic contingency', bs: 'synergize scalable supply-chains' } } ]

      This means you’ve successfully made a GET request with the core Node.js library.

      The get() method you used is a convenient method Node.js provides because GET requests are a very common type of request. Node.js provides a request() method to make a request of any type. Next, this tutorial will examine how to make a GET request with request().

      Making Requests with request()

      The request() method supports multiple function signatures. You’ll use this one for the subsequent example:

      https.request(URL_String, Options_Object, Callback_Function) {
          Action
      }
      

      The first argument is a string with the API endpoint. The second argument is a JavaScript object containing all the options for the request. The last argument is a callback function to handle the response.

      Create a new file for a new module called getRequestWithRequest.js:

      • nano getRequestWithRequest.js

      The code you will write is similar to the getRequestWithGet.js module you wrote earlier. First, import the https module:

      requests/getRequestWithRequest.js

      const https = require('https');
      

      Next, create a new JavaScript object that contains a method key:

      requests/getRequestWithRequest.js

      const https = require('https');
      
      const options = {
        method: 'GET'
      };
      

      The method key in this object will tell the request() function what HTTP method the request is using.

      Next, make the request in your code. The following codeblock highlights code that was different from the request made with the get() method. In your editor, enter all of the following lines:

      requests/getRequestWithRequest.js

      ...
      
      let request = https.request('https://jsonplaceholder.typicode.com/users?_limit=2', options, (res) => {
        if (res.statusCode !== 200) {
          console.error(`Did not get an OK from the server. Code: ${res.statusCode}`);
          res.resume();
          return;
        }
      
        let data="";
      
        res.on('data', (chunk) => {
          data += chunk;
        });
      
        res.on('close', () => {
          console.log('Retrieved all data');
          console.log(JSON.parse(data));
        });
      });
      
      request.end();
      
      request.on('error', (err) => {
        console.error(`Encountered an error trying to make a request: ${err.message}`);
      });
      

      To make a request using request(), you provide the URL in the first argument, an object with the HTTP options in the second argument, and a callback to handle the response in the third argument.

      The options variable you created earlier is the second argument, telling Node.js that this is a GET request. The callback is unchanged from when you first wrote it.

      You also call the end() method of the request variable. This is an important method that must be called when using the request() function. It completes the request, allowing it to be sent. If you don’t call it, the program will never complete, as Node.js will think you still have data to add to the request.

      Save and exit nano with CTRL+X, or the equivalent with your text editor.

      Run this program in your terminal:

      • node getRequestWithRequest.js

      You will receive this output, which is the same as the first module:

      Output

      Retrieved all data [ { id: 1, name: 'Leanne Graham', username: 'Bret', email: 'Sincere@april.biz', address: { street: 'Kulas Light', suite: 'Apt. 556', city: 'Gwenborough', zipcode: '92998-3874', geo: [Object] }, phone: '1-770-736-8031 x56442', website: 'hildegard.org', company: { name: 'Romaguera-Crona', catchPhrase: 'Multi-layered client-server neural-net', bs: 'harness real-time e-markets' } }, { id: 2, name: 'Ervin Howell', username: 'Antonette', email: 'Shanna@melissa.tv', address: { street: 'Victor Plains', suite: 'Suite 879', city: 'Wisokyburgh', zipcode: '90566-7771', geo: [Object] }, phone: '010-692-6593 x09125', website: 'anastasia.net', company: { name: 'Deckow-Crist', catchPhrase: 'Proactive didactic contingency', bs: 'synergize scalable supply-chains' } } ]

      You have now used the request() method to make a GET request. It’s important to know this function as it allows you to customize your request in ways the get() method cannot, like making requests with other HTTP methods.

      Next, you will configure and customize your requests with the request() function.

      Step 2 — Configuring HTTP request() Options

      The request() function allows you to send HTTP requests without specifying the URL in the first argument. In this case, the URL would be contained with the options object, and the request() would have this function signature:

      https.request(Options_Object, Callback_Function) {
          Action
      }
      

      In this step, you will use this functionality to configure your request() with the options object.

      Node.js allows you to enter the URL in the options object you pass to the request. To try this out, reopen the getRequestWithRequest.js file:

      • nano getRequestWithRequest.js

      Remove the URL from the request() call so that the only arguments are the options variable and the callback function:

      requests/getRequestWithRequest.js

      const https = require('https');
      
      const options = {
        method: 'GET',
      };
      
      let request = https.request(options, (res) => {
      ...
      

      Now add the following properties to the options object:

      requests/getRequestWithRequest.js

      const https = require('https');
      
      const options = {
        host: 'jsonplaceholder.typicode.com',
        path: '/users?_limit=2',
        method: 'GET'
      };
      
      let request = https.request(options, (res) => {
      ...
      

      Instead of one string URL, you have two properties—host and path. The host is the domain name or IP address of the server you’re accessing. The path is everything that comes after the domain name, including query parameters (values after the question mark).

      The options object can hold other useful data that goes into a request. For example, you can provide request headers in the options. Headers typically send metadata about the request.

      When developers create APIs, they may choose to support different data formats. One API endpoint may be able to return data in JSON, CSV, or XML. In those APIs, the server may look at the Accept header to determine the correct response type.

      The Accept header specifies the type of data the user can handle. While the API being used in these examples only return JSON, you can add the Accept header to your request to explicitly state that you want JSON.

      Add the following lines of code to append the Accept header:

      requests/getRequestWithRequest.js

      const https = require('https');
      
      const options = {
        host: 'jsonplaceholder.typicode.com',
        path: '/users?_limit=2',
        method: 'GET',
        headers: {
          'Accept': 'application/json'
        }
      };
      

      By adding headers, you’ve covered the four most popular options that are sent in Node.js HTTP requests: host, path, method, and headers. Node.js supports many more options; you can read more at the official Node.js docs for more information.

      Enter CTRL+X to save your file and exit nano.

      Next, run your code once more to make the request by only using options:

      • node getRequestWithRequest.js

      The results will be the same as your previous runs:

      Output

      Retrieved all data [ { id: 1, name: 'Leanne Graham', username: 'Bret', email: 'Sincere@april.biz', address: { street: 'Kulas Light', suite: 'Apt. 556', city: 'Gwenborough', zipcode: '92998-3874', geo: [Object] }, phone: '1-770-736-8031 x56442', website: 'hildegard.org', company: { name: 'Romaguera-Crona', catchPhrase: 'Multi-layered client-server neural-net', bs: 'harness real-time e-markets' } }, { id: 2, name: 'Ervin Howell', username: 'Antonette', email: 'Shanna@melissa.tv', address: { street: 'Victor Plains', suite: 'Suite 879', city: 'Wisokyburgh', zipcode: '90566-7771', geo: [Object] }, phone: '010-692-6593 x09125', website: 'anastasia.net', company: { name: 'Deckow-Crist', catchPhrase: 'Proactive didactic contingency', bs: 'synergize scalable supply-chains' } } ]

      As APIs can vary from provider to provider, being comfortable with the options object is key to adapting to their differing requirements, with the data types and headers being some of the most common variations.

      So far, you have only done GET requests to retrieve data. Next, you will make a POST request with Node.js so you can upload data to a server.

      Step 3 — Making a POST Request

      When you upload data to a server or want the server to create data for you, you typically send a POST request. In this section, you’ll create a POST request in Node.js. You will make a request to create a new user in the users API.

      Despite being a different method from GET, you will be able to reuse code from the previous requests when writing your POST request. However, you will have to make the following adjustments:

      • Change the method in the options object to POST
      • Add a header to state you are uploading JSON
      • Check the status code to confirm a user was created
      • Upload the new user’s data

      To make these changes, first create a new file called postRequest.js. Open this file in nano or an alternative text editor:

      Begin by importing the https module and creating an options object:

      requests/postRequest.js

      const https = require('https');
      
      const options = {
        host: 'jsonplaceholder.typicode.com',
        path: '/users',
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json; charset=UTF-8'
        }
      };
      

      You change the path to match what’s required for POST requests. You also updated the method to POST. Lastly, you added a new header in your options Content-Type. This header tells the server what type of data you are uploading. In this case, you’ll be uploading JSON data with UTF-8 encoding.

      Next, make the request with the request() function. This is similar to how you made GET requests, but now you look for a different status code than 200. Add the following lines to the end of your code:

      requests/postRequest.js

      ...
      const request = https.request(options, (res) => {
        if (res.statusCode !== 201) {
          console.error(`Did not get a Created from the server. Code: ${res.statusCode}`);
          res.resume();
          return;
        }
      
        let data="";
      
        res.on('data', (chunk) => {
          data += chunk;
        });
      
        res.on('close', () => {
          console.log('Added new user');
          console.log(JSON.parse(data));
        });
      });
      

      The highlighted line of code checks if the status code is 201. The 201 status code is used to indicate that the server created a resource.

      This POST request is meant to create a new user. For this API, you need to upload the user details. Create some user data and send that with your POST request:

      requests/postRequest.js

      ...
      
      const requestData = {
        name: 'New User',
        username: 'digitalocean',
        email: 'user@digitalocean.com',
        address: {
          street: 'North Pole',
          city: 'Murmansk',
          zipcode: '12345-6789',
        },
        phone: '555-1212',
        website: 'digitalocean.com',
        company: {
          name: 'DigitalOcean',
          catchPhrase: 'Welcome to the developer cloud',
          bs: 'cloud scale security'
        }
      };
      
      request.write(JSON.stringify(requestData));
      

      You first created the requestData variable, which is a JavaScript object containing user data. Your request does not include an id field, as servers typically generate these while saving the new data.

      You next use the request.write() function, which accepts a string or buffer object to send along with the request. As your requestData variable is an object, you used the JSON.stringify function to convert it to a string.

      To complete this module, end the request and check for errors:

      requests/postRequest.js

      ...
      
      request.end();
      
      request.on('error', (err) => {
        console.error(`Encountered an error trying to make a request: ${err.message}`);
      });
      

      It’s important that you write data before you use the end() function. The end() function tells Node.js that there’s no more data to be added to the request and sends it.

      Save and exit nano by pressing CTRL+X.

      Run this program to confirm that a new user was created:

      The following output will be displayed:

      Output

      Added new user { name: 'New User', username: 'digitalocean', email: 'user@digitalocean.com', address: { street: 'North Pole', city: 'Murmansk', zipcode: '12345-6789' }, phone: '555-1212', website: 'digitalocean.com', company: { name: 'DigitalOcean', catchPhrase: 'Welcome to the developer cloud', bs: 'cloud scale security' }, id: 11 }

      The output confirms that the request was successful. The API returned the user data that was uploaded, along with the ID that was assigned to it.

      Now that you have learned how to make POST requests, you can upload data to servers in Node.js. Next you will try out PUT requests, a method used to update data in a server.

      Step 4 — Making a PUT Request

      Developers make a PUT request to upload data to a server. While this may be similar to POST requests, PUT requests have a different function. PUT requests are idempotent—you can run a PUT request multiple times and it will have the same result.

      In practice, the code you write is similar to that of a POST request. You set up your options, make your request, write the data you want to upload, and verify the response.

      To try this out, you’re going to create a PUT request that updates the first user’s username.

      As the code is similar to the POST request, you’ll use that module as a base for this one. Copy the postRequest.js into a new file, putRequest.js:

      • cp postRequest.js putRequest.js

      Now open putRequest.js in a text editor:

      Make these highlighted changes so that you send a PUT request to https://jsonplaceholder.typicode.com/users/1:

      requests/putRequest.js

      const https = require('https');
      
      const options = {
        host: 'jsonplaceholder.typicode.com',
        path: '/users/1',
        method: 'PUT',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json; charset=UTF-8'
        }
      };
      
      const request = https.request(options, (res) => {
        if (res.statusCode !== 200) {
          console.error(`Did not get an OK from the server. Code: ${res.statusCode}`);
          res.resume();
          return;
        }
      
        let data="";
      
        res.on('data', (chunk) => {
          data += chunk;
        });
      
        res.on('close', () => {
          console.log('Updated data');
          console.log(JSON.parse(data));
        });
      });
      
      const requestData = {
        username: 'digitalocean'
      };
      
      request.write(JSON.stringify(requestData));
      
      request.end();
      
      request.on('error', (err) => {
        console.error(`Encountered an error trying to make a request: ${err.message}`);
      });
      

      You first change the path and method properties of the options object. path in this case identifies the user that you are going to update. When you make the request, you check if the response code was 200, meaning that the request was OK. The data you are uploading now only contains the property you are updating.

      Save and exit nano with CTRL+X.

      Now execute this Node.js program in your terminal:

      You will receive this output:

      Output

      Updated data { username: 'digitalocean', id: 1 }

      You sent a PUT request to update a pre-existing user.

      So far you have learned how to retrieve, add, and update data. To give us a full command of managing data via APIs, you’ll next make a DELETE request to remove data from a server.

      Step 5 — Making a DELETE Request

      The DELETE request is used to remove data from a server. It can have a request body, but most APIs tend not to require them. This method is used to delete an entire object from the server. In this section, you are going to delete a user using the API.

      The code you will write is similar to that of a GET request, so use that module as a base for this one. Copy the getRequestWithRequest.js file into a new deleteRequest.js file:

      • cp getRequestWithRequest.js deleteRequest.js

      Open deleteRequest.js with nano:

      Now modify the code at the highlighted parts, so you can delete the first user in the API:

      requests/putRequest.js

      const https = require('https');
      
      const options = {
        host: 'jsonplaceholder.typicode.com',
        path: '/users/1',
        method: 'DELETE',
        headers: {
          'Accept': 'application/json',
        }
      };
      
      const request = https.request(options, (res) => {
        if (res.statusCode !== 200) {
          console.error(`Did not get an OK from the server. Code: ${res.statusCode}`);
          res.resume();
          return;
        }
      
        let data="";
      
        res.on('data', (chunk) => {
          data += chunk;
        });
      
        res.on('close', () => {
          console.log('Deleted user');
          console.log(JSON.parse(data));
        });
      });
      
      request.end();
      
      request.on('error', (err) => {
        console.error(`Encountered an error trying to make a request: ${err.message}`);
      });
      

      For this module, you begin by changing the path property of the options object to the resource you want to delete—the first user. You then change the method to DELETE.

      Save and exit this file by pressing CTRL+X.

      Run this module to confirm it works. Enter the following command in your terminal:

      The program will output this:

      Output

      Deleted user {}

      While the API does not return a response body, you still got a 200 response so the request was OK.

      You’ve now learned how to make DELETE requests with Node.js core modules.

      Conclusion

      In this tutorial, you made GET, POST, PUT, and DELETE requests in Node.js. No libraries were installed; these requests were made using the standard https module. While GET requests can be made with a get() function, all other HTTP methods are done via the request() method.

      The code you wrote was written for a publicly available, test API. However, the way you write requests will work for all types of APIs. If you would like to learn more about APIs, check out our API topic page. For more on developing in Node.js, return to the How To Code in Node.js series.



      Source link

      So konfigurieren Sie Apache HTTP mit MPM Event und PHP-FPM unter Ubuntu 18.04


      Der Autor hat den COVID-19 Relief Fund dazu ausgewählt, eine Spende im Rahmen des Programms Write for DOnations zu erhalten.

      Einführung

      Der Apache-HTTP-Webserver wurde im Laufe der Jahre weiterentwickelt, damit er in verschiedenen Umgebungen arbeitet und verschiedene Anforderungen erfüllt. Ein wichtiges Problem, das Apache HTTP wie jeder andere Webserver auch lösen muss, ist die Handhabung verschiedener Prozesse bei der Bearbeitung von http-basierten Anfragen. Dazu zählt das Öffnen eines Sockets, das die Anforderung verarbeitet, das Offenhalten der Verbindung für eine bestimmte Zeit, die Handhabung neuer Ereignisse, die während dieser Verbindung eintreten und die Rückgabe des produzierten Contents durch ein Programm, dass in einer bestimmten Sprache geschrieben wurde (wie PHP, Perl oder Python). Diese Aufgaben werden von einem Multi-Processing-Module (MPM) ausgeführt und gesteuert.

      Apache HTTP ist mit drei verschiedenen MPM ausgestattet:

      • Prefork: Für jede eingehende Verbindung, die den Server erreicht, wird ein neuer Vorgang erstellt. Jeder Vorgang ist isoliert von den anderen und es wird kein Speicher zwischen ihnen geteilt, selbst dann, wenn sie in der Ausführung identische Anrufe an einem bestimmten Punkt ausführen. Auf diese Weise können Sie mit Bibliotheken verknüpfte Anwendungen, die Thread-Ausführungen nicht unterstützen, sicher ausführen – meist ältere Anwendungen oder Bibliotheken.
      • Worker: Ein Elternprozess ist für das Starten eines Bündels von Kindprozessen verantwortlich, von denen einige neu eingehende Verbindungen erfassen und andere den angeforderten Content bereitstellen. Für jeden Prozess gibt es einen dazugehörigen Thread (ein einzelner Thread kann jeweils eine Verbindung verwalten), sodass ein Prozess mit mehreren Anfragen gleichzeitig umgehen kann. Diese Methode für die Handhabung von Verbindungen fördert eine bessere Ressourcennutzung und gewährleistet die Aufrechterhaltung der Stabilität. Das ist auf das Bündel von verfügbaren Prozessen zurückzuführen, bei denen oft frei verfügbare Threads bereitstehen, die neue Verbindungen sofort bedienen können.
      • Event: Basierend auf Worker geht dieses MPM noch einen Schritt weiter, indem es die Art und Weise optimiert, wie der Elternprozess Aufgaben für die Kindprozesse und für die Threads, die damit verknüpft sind, vorgibt. Eine Verbindung bleibt für 5 Sekunden standardmäßig geöffnet und schließt sich bei jedem neuen Ereignis, das eintritt; das ist der Standardwert für die Keep-Alive-Anweisung, der den mit ihm verknüpften Thread beibehält. Das Event MPM ermöglicht dem Prozess das Verwalten von Threads, damit einige Threads für die Verwaltung neuer eingehender Verbindungen bereitstehen, während andere weiterhin mit den Live-Verbindungen verknüpft sind. Die Ressourcennutzung und Leistungsfähigkeit wird dadurch verbessert, dass die den Threads zugewiesenen Aufgaben neu verteilt werden können.

      Mit dem MPM Event-Modul ist ein schnelles Multi-Processing-Modul auf dem Apache-HTTP-Webserver verfügbar.

      PHP-FPM ist der FastCGI-Prozessmanager für PHP. Das FastCGI-Protokoll basiert auf dem Common Gateway Interface (CGI), einem Protokoll, das zwischen Anwendungen und Webservern wie Apache HTTP steht. Dadurch können Entwickler Anwendungen schreiben, ohne das Verhalten der Webserver berücksichtigen zu müssen. Die Programme führen ihre Prozesse unabhängig aus und übergeben ihr Produkt über dieses Protokoll an den Webserver. Jede neue Verbindung, die von einer Anwendung verarbeitet werden muss, erstellt einen neuen Prozess.

      Durch die Kombination von MPM Event in Apache HTTP mit dem PHP FastCGI-Prozessmanager (PHP-FPM) kann eine Website schneller laden und mehr gleichzeitige Verbindungen mit weniger Ressourcen verarbeiten.

      In diesem Tutorial verbessern Sie die Leistung des LAMP-Stacks, indem Sie das standardmäßige Multi-Processing-Module von Prefork auf Event umstellen und den PHP-FPM-Prozessmanager für die Handhabung des PHP-Codes nutzen anstelle des klassischen mod_php in Apache HTTP.

      Voraussetzungen

      Bevor Sie diese Anleitung beginnen, benötigen Sie Folgendes:

      Schritt 1 — Umstellen des Multi-Processing-Module

      Ubuntu übernimmt Skripte, um Apache-HTTP-Module über die eigene übergeordnete Distribution Debian zu aktivieren oder zu deaktivieren. Sie werden dieses Toolset in diesem Schritt verwenden, um das Prefork-Modul zu deaktivieren und das Event-Modul zu aktivieren.

      In diesem Schritt halten Sie Apache HTTP an, deaktivieren das Modul PHP 7.2, das mit dem Prefork-Modul verknüpft ist, und deaktivieren anschließend Prefork, um das Event-Modul unmittelbar aktivieren zu können.

      Zuerst halten Sie den Apache-HTTP-Dienst an:

      • sudo systemctl stop apache2

      Nun können Sie das Modul PHP 7.2 deaktivieren, das mit dem Prefork-Modul in Verbindung steht:

      Deaktivieren Sie dann das Prefork MPM-Modul:

      • sudo a2dismod mpm_prefork

      Nun Aktivieren Sie das Event MPM-Modul:

      Sie haben das MPM von Prefork auf Event umgestellt und die Modulverbindung PHP 7.2 zwischen PHP und Apache HTTP entfernt. Im nächsten Schritt installieren Sie das php-fpm-Modul sowie die verwandten Bibliotheken und Proxy-Module. Sie konfigurieren Apache HTTP so, dass es auch mit PHP kommunizieren kann.

      Schritt 2 — Konfigurieren von Apache HTTP für die Nutzung des FastCGI-Prozesses

      In dieser Phase haben Sie die Verarbeitung von Verbindungen durch Apache HTTP umgestellt, indem Sie sie von dem Prefork-MPM auf Event verlagert haben. Im Zuge dessen haben Sie jedoch das PHP-Modul deaktiviert, das Apache HTTP mit jedem Programm verbunden hatte, das mit PHP ausgeführt wird.

      In diesem Schritt installieren Sie den PHP-FPM-Prozessor, damit Apache HTTP wieder PHP-Programme verarbeiten kann. Außerdem installieren Sie die Abhängigkeitsbibliotheken und aktivieren die Module, damit beide reibungslos und schneller zusammenarbeiten können als zuvor.

      Installieren Sie zuerst php-fpm. Der folgende Befehl installiert das PHP-FPM und aktiviert automatisch den Dienst php7.2-fpm, der in systemd integriert ist, sodass der Dienst beim Booten gestartet wird:

      Apache HTTP und PHP benötigen für die Kommunikation eine Bibliothek, die diese Funktion ermöglicht. Nun installieren Sie libapache2-mod-fcgid, das als Schnittstelle zwischen Programmen mit Webservern dient und Apache-HTTP-spezifisch ist. Diese Kommunikation erfolgt über ein UNIX-Socket.

      Installieren Sie diese Bibliothek:

      • sudo apt install libapache2-mod-fcgid

      Sie haben php-fpm und das libapache2-mod-fcgid installiert, aber noch keines davon aktiviert.

      Aktivieren Sie zuerst das php-fpm-Modul mit folgendem Befehl:

      Aktivieren Sie in einem zweiten Schritt das Apache HTTP-Proxy-Modul:

      Aktivieren Sie in einem dritten Schritt das FastCGI-Proxy-Modul auf Apache HTTP:

      Hinweis: Sie können die Konfiguration dieser Interaktion zwischen PHP-Programmen und Apache HTTP über einen UNIX-Socket mit Folgendem lesen:

      • cat /etc/apache2/conf-enabled/php7.2-fpm.conf

      Nun wurden alle Vorkehrungen getroffen, damit Sie Apache HTTP starten können. Führen Sie eine Konfigurationsüberprüfung durch:

      • sudo apachectl configtest

      Output

      Syntax OK

      Danach können Sie mit dem Neustart von Apache HTTP fortfahren, da es beim Installieren der FastCGI-Bibliothek libapache2-mod-fcgid automatisch gestartet wurde:

      • sudo systemctl restart apache2

      Sie haben das php-fpm-Modul installiert und Apache HTTP so konfiguriert, dass es damit funktioniert. Zudem haben Sie ermöglicht, dass die erforderlichen Module für das FastCGI-Protokoll funktionieren, und die entsprechenden Dienste gestartet.

      Nachdem Apache das Event MPM-Modul aktiviert hat und PHP-FPM verfügbar ist und ausgeführt wird, ist es an der Zeit sicherzustellen, das alles wie geplant funktioniert.

      Schritt 3 — Testen Ihrer Konfiguration

      Führen Sie einige Tests aus, um zu prüfen, ob die Konfigurationsänderungen angewendet wurden. Beim ersten Test wird geprüft, welches Multi-Processing-Modul Apache HTTP verwendet. Beim zweiten Test wird sichergestellt, dass PHP den FPM-Manager verwendet.

      Überprüfen Sie den Apache-HTTP-Server, indem Sie den folgenden Befehl ausführen:

      • sudo apachectl -M | grep 'mpm'

      Sie erhalten folgende Ausgabe:

      Output

      mpm_event_module (shared)

      Für das Proxy-Modul und FastCGI können Sie diese Prozedur wiederholen:

      • sudo apachectl -M | grep 'proxy'

      Die Ausgabe zeigt Folgendes:

      Output

      proxy_module (shared) proxy_fcgi_module (shared)

      Wenn Sie die gesamte Liste der Module sehen möchten, können Sie den zweiten Teil des Befehls nach -M entfernen.

      Nun ist es Zeit zu prüfen, ob PHP den FastCGI-Prozessmanager verwendet. Dazu schreiben Sie ein kleines PHP-Skript, das Ihnen alle Informationen zeigt, die mit PHP in Verbindung stehen.

      Führen Sie den folgenden Befehl aus, um eine Datei zu schreiben, deren Name wie folgt lautet:

      • sudo nano /var/www/your_domain/info.php

      Fügen Sie den folgenden Inhalt in die Datei info.php ein:

      info.php

      <?php phpinfo(); ?>
      

      Rufen Sie nun die URL Ihres Servers auf und fügen Sie info.php am Ende hinzu: http://your_domain/info.php.

      Der Server-API-Eintrag lautet FPM/FastCGI.

      PHP Screen the Server API entry FPM/FastCGI

      Löschen Sie die Datei info.php nach diesem Test, damit keine Informationen über den Server veröffentlicht werden:

      • sudo rm /var/www/yourdomain.com/info.php

      Sie haben den Betriebszustand des MPM-Moduls und der Module, die für die Handhabung von FastCGI zuständig sind, sowie die Handhabung des PHP-Codes überprüft.

      Zusammenfassung

      Sie haben Ihren ursprünglichen LAMP-Stack optimiert, sodass sich die Anzahl der Verbindungen zur Erstellung neuer Apache HTTP-Prozesse erhöht hat, PHP-FPM den PHP-Code effizienter verwaltet und sich die Ressourcennutzung insgesamt verbessert.

      Weitere Informationen zu den verschiedenen Modulen und verwandten Projekten finden Sie in der Projekt-Dokumentation zum Apache HTTP-Server.



      Source link

      Comment configurer Apache HTTP avec MPM Event et PHP-FPM sur Ubuntu 18.04


      L’auteur a choisi le COVID-19 Relief Fund pour recevoir un don dans le cadre du programme Write for DOnations.

      Introduction

      Au fil des années, le serveur Web Apache HTTP a évolué. Il fonctionne aujourd’hui dans différents environnements et répond à différents besoins. Comme tout serveur Web, un des problèmes importants qu’Apache HTTP doit résoudre est de savoir de quelle manière gérer différents processus pour servir une requête de protocole http. Cela implique d’ouvrir une socket, de traiter la requête, de maintenir la connexion ouverte pendant une certaine période, de gérer les nouveaux événements se produisant via cette connexion et de renvoyer le contenu produit par un programme créé dans un langage particulier (comme PHP, Perl ou Python). Ces tâches sont effectuées et contrôlées par un Multi-Processing Module (MPM).

      Apache HTTP est livré avec trois MPM différents :

      • Pre-fork : un nouveau processus est créé pour chaque connexion entrante atteignant le serveur. Chaque processus est isolé des autres. Donc, même s’ils effectuent des appels identiques à un certain moment, ils ne partagent aucune mémoire. Il s’agit d’un moyen sûr d’exécuter des applications liées à des bibliothèques qui ne prennent pas en charge le threading, généralement des applications ou des bibliothèques plus anciennes.
      • Worker : un processus parent a pour responsabilité de lancer un pool de processus enfants, certains écoutant les nouvelles connexions entrantes et d’autres servant le contenu demandé. Chaque processus est threadé (un seul thread pour gérer une connexion), donc un processus peut gérer plusieurs requêtes simultanément. Cette méthode de traitement des connexions permet une meilleure utilisation des ressources, tout en maintenant la stabilité. Cela est permis grâce au pool de processus disponibles, qui dispose souvent de threads gratuits prêts à servir de nouvelles connexions immédiatement.
      • Event : en fonction du travailleur, ce MPM va plus loin en optimisant la façon dont le processus parent planifie les tâches pour les processus enfants et les threads qui y sont associés. Par défaut, une connexion reste ouverte pendant 5 secondes. Si aucun nouvel événement ne se produit, elle se ferme. Il s’agit de la valeur par défaut de la directive keep-alive, qui conserve le thread qui lui est associé. Le MPM Event permet au processus de gérer les threads afin que certains soient libres de gérer les nouvelles connexions entrantes tandis que d’autres sont liés aux connexions actives. En autorisant ainsi la redistribution des tâches affectées aux threads, l’utilisation des ressources et les performances sera optimisée.

      Le module MPM Event est un module de multi-traitement rapide disponible sur le serveur Web Apache HTTP.

      PHP-FPM est le Gestionnaire de processus FastCGI pour PHP. Le protocole FastCGI est basé sur la Common Gateway Interface (CGI), un protocole qui se situe entre les applications et les serveurs Web comme Apache HTTP. Cela permet aux développeurs d’écrire des applications indépendamment du comportement des serveurs Web. Les programmes exécutent leurs processus de manière indépendante et transmettent leur produit au serveur Web via ce protocole. Chaque nouvelle connexion qui devra être traitée par une application qui créera un nouveau processus.

      En combinant MPM Event dans Apache HTTP et le Gestionnaire de processus PHP FastCGI (PHP-FPM), le chargement d’un site Web se fait plus rapidement et il pourra gérer un plus grand nombre de connexions simultanées tout en utilisant moins de ressources.

      Dans ce tutoriel, vous améliorerez les performances de la pile LAMP en remplaçant le module de multi-traitement par défaut de pré-fork par un événement et en utilisant le gestionnaire de processus PHP-FPM pour gérer le code PHP au lieu du mod_php traditionnel d’Apache HTTP.

      Conditions préalables

      Avant de commencer ce guide, vous aurez besoin des éléments suivants :

      Étape 1 – Changement du module multi-traitement

      Ubuntu hérite de scripts pour activer ou désactiver les modules HTTP Apache de sa distribution parente, Debian. Vous utiliserez cet ensemble d’outils dans cette étape pour désactiver le module Pre-fork et activer le module Event.

      Au cours cette étape, vous allez arrêter Apache HTTP, désactiver le module PHP 7.2 lié au module Pre-fork, puis désactiver Pre-fork pour activer immédiatement le module Event.

      Vous allez tout d’abord arrêter le service HTTP Apache :

      • sudo systemctl stop apache2

      Vous pouvez maintenant désactiver le module PHP 7.2, qui est lié au module Pre-fork :

      Ensuite, désactivez le module Pre-fork MPM :

      • sudo a2dismod mpm_prefork

      Maintenant, activez le module Event MPM :

      Vous avez changé le MPM de pre-fork en event et supprimé la connexion du module PHP 7.2 entre PHP et Apache HTTP. À l’étape suivante, vous installerez le module php-fpm, ainsi que les bibliothèques et modules proxy associés. Vous allez configurer Apache HTTP pour qu’il puisse également communiquer avec PHP.

      Étape 2 – Configuration d’Apache HTTP pour utiliser le Gestionnaire de processus FastCGI

      À ce stade, vous avez changé la méthode de traitement des connexions d’Apache HTTP en déplaçant de Pre-fork MPM à Event. Cependant, au cours du processus, vous avez désactivé le module PHP qui connectait Apache HTTP à tout programme fonctionnant sur PHP.

      Au cours de cette étape, vous allez installer le processeur PHP-FPM pour permettre à Apache HTTP de traiter à nouveau les programmes PHP. Vous installerez également les bibliothèques de dépendances et activerez les modules afin que les deux puissent coopérer avec fluidité et plus rapidement qu’auparavant.

      Tout d’abord, installez php-fpm. La commande suivante installera le package PHP-FPM et activera automatiquement le service php7.2-fpm intégré à systemd, de sorte que le service se lance au démarrage :

      Pour communiquer, Apache HTTP et PHP ont besoin d’une bibliothèque permettant cette capacité. Vous allez maintenant installer libapache2-mod-fcgid. Il peut servir d’interface entre des programmes avec des serveurs Web et il est spécifique à Apache HTTP. Cette communication se produira via une socket UNIX.

      Installez cette bibliothèque :

      • sudo apt install libapache2-mod-fcgid

      Vous avez installé php-fpm et la libapache2-mod-fcgid, mais aucune des deux n’est encore activée.

      Tout d’abord, activez le module php-fpm avec la commande suivante :

      Ensuite, activez le module proxy d’Apache HTTP :

      Pour finir, activez le module proxy FastCGI dans Apache HTTP :

      Note : vous pouvez lire la configuration de cette interaction entre les programmes PHP et Apache HTTP via une socket UNIX avec ce qui suit :

      • cat /etc/apache2/conf-enabled/php7.2-fpm.conf

      Tout est maintenant en place pour démarrer Apache HTTP. Vous allez tout d’abord procéder à un contrôle de configuration :

      • sudo apachectl configtest

      Output

      Syntax OK

      Après cela, vous pouvez redémarrer Apache HTTP, puisqu’il a été démarré automatiquement lors de l’installation de la bibliothèque FastCGI libapache2-mod-fcgid :

      • sudo systemctl restart apache2

      Vous avez installé le module php-fpm, configuré Apache HTTP pour fonctionner avec lui, activé les modules nécessaires pour que le protocole FastCGI fonctionne et démarre les services correspondants.

      Maintenant qu’Apache a activé le module Event MPM et que PHP-FPM est présent et en cours d’exécution, il est temps de vérifier si tout fonctionne comme prévu.

      Étape 3 – Vérification de votre configuration

      Vous allez exécuter ces tests afin de vérifier que les modifications de configuration ont bien été appliquées. Le premier test consiste à vérifier quel module multi-traitement Apache HTTP utilise. Le second à vérifier que PHP utilise le gestionnaire FPM.

      Vérifiez le serveur Apache HTTP en exécutant la commande suivante :

      • sudo apachectl -M | grep 'mpm'

      Votre sortie sera la suivante :

      Output

      mpm_event_module (shared)

      Vous pouvez refaire la même chose pour le module proxy et FastCGI :

      • sudo apachectl -M | grep 'proxy'

      Le résultat sera :

      Output

      proxy_module (shared) proxy_fcgi_module (shared)

      Pour voir la liste complète des modules, vous pouvez supprimer la deuxième partie de la commande après -M.

      Il est maintenant temps de vérifier si PHP utilise le Gestionnaire de processus FastCGI. Pour cela, vous allez écrire un petit script PHP qui vous donnera toutes les informations liées à PHP.

      Exécutez la commande suivante pour écrire un fichier nommé de la manière suivante :

      • sudo nano /var/www/your_domain/info.php

      Ajoutez le contenu suivant dans le fichier info.php :

      info.php

      <?php phpinfo(); ?>
      

      Maintenant, naviguez vers l’URL de votre serveur et ajoutez info.php à la fin comme ceci : http://your_domain/info.php.

      L’entrée API du serveur sera FPM/FastCGI.

      PHP balaye l'entrée de l'API du serveur FPM/FastCGI

      Supprimez le fichier info.php après cette vérification afin qu’aucune information ne puisse être divulguée publiquement sur le serveur :

      • sudo rm /var/www/yourdomain.com/info.php

      Vous avez vérifié l’état de fonctionnement du module MPM, les modules gérant le FastCGI et le traitement du code PHP.

      Conclusion

      Vous avez optimisé votre pile LAMP d’origine,en augmentant ainsi le nombre de connexions pour créer de nouveaux processus HTTP Apache. PHP-FPM permettra de traiter le code PHP plus efficacement et l’utilisation globale des ressources est meilleure.

      Pour plus d’informations sur les différents modules et les projets associés, consultez la documentation sur le projet de serveur Apache HTTP.



      Source link