We have a GPS device socket handling server using NodeJS which sends the received HTTPS request to Apache installed server and saving the data into MySQL Database. When we restart NodeJS or Apache installed server, Request Handling rate of the Apache installed server gets really slow. As far now, we have checked MySQL performance and its working properly. Per second only 5 to 15 requests may be triggered from NodeJS server, In normal situation its working fine but after restart the server goes very worse. After several hours, automatically the problem solves. Please do guide, how to resolve this issue and required details to share for monitoring it?
Server details:
Ubuntu server with 8GB RAM and 4 Cores processor.
MySQL Config:
key_buffer_size = 16M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 8
query_cache_limit = 1M
query_cache_size = 16M
max_binlog_size = 100M
innodb_log_file_size=512M
innodb_buffer_pool_size=6G
innodb_buffer_pool_instances=6
innodb_flush_log_at_trx_commit=2
innodb_flush_method=O_DIRECT_NO_FSYNC
innodb_log_files_in_group=5
innodb_open_files=1000
sync_binlog=0
max_connections=512
table_open_cache=1000
table_open_cache_instances=16
back_log=1000
query_cache_limit=2M
query_cache_size=0
query_cache_type=0
sort_buffer_size=32M
read_rnd_buffer_size=32M
Top Command: Top Process list, MySQL using 6.8GB
After sometime, MySQL restarts automatically and server getting slow again.
Apache Buddy
[ -- ] Parent PID: 19547.
[ OK ] Memory usage of parent PID is less than 50MB: 7268 Kilobytes.
[ -- ] Apache has been running 0d 23h 19m 11s.
[ !! ] *** LOW UPTIME ***.
[ @@ ] The following recommendations may be misleading - apache has been restarted within the last 24 hours.
[ -- ] Your server has 7976 MB of PHYSICAL memory.
[ -- ] Your ServerLimit setting is 512.
[ -- ] Your MaxRequestWorkers setting is 512.
[ OK ] Current Apache Process Count is 45, including the parent PID.
[ -- ] Number of vhosts detected: 5.
[ -- ] |________ of which 3 are HTTP (specifically, port 80).
[ -- ] |________ of which 2 are HTTPS (specifically, port 443).
[ OK ] Current Apache vHost Count is less than maxrequestworkers.
[ >> ] MaxRequestsPerChild directive not found.
[ -- ] This server is NOT running Plesk.
[ -- ] This server is NOT running cPanel.
[ -- ] This server is NOT running Virtualmin.
[ -- ] Your PHP Memory Limit (Per-Process) is 128M.
[ -- ] MySQL Detected => Using 7038.63 MB of memory.
[ OK ] No large log files were found in /var/log/apache2.
[ OK ] MaxClients has not been hit recently.
[ >> ] Apache only logs maxclients/maxrequestworkers hits once in a lifetime, if no restart has happened this event may have been rotated away.
[ >> ] As a backup check, please compare number of running apache processes (minus 1 for parent) against maxclients/maxrequestworkers.
[ OK ] No PHP Fatal Errors were found.
[ -- ] apache2 is currently using 1308.65 MB of memory.
[ -- ] The smallest apache process is using 9.73 MB of memory
[ -- ] The average apache process is using 9.82 MB of memory
[ -- ] The largest apache process is using 10.19 MB of memory
[ !! ] Going by the average Apache process, Apache can potentially use 5027.85 MB RAM:
Without considering services: 63.04 % of total installed RAM
Considering extra services: 536.38 % of remaining RAM
[ !! ] Going by the largest Apache process, Apache can potentially use 5217.28 MB RAM:
Without considering services: 65.42 % of total installed RAM
Considering extra services: 556.59 % of remaining RAM
--------------------------------------------------------------------------------
### GENERAL FINDINGS & RECOMMENDATIONS ###
--------------------------------------------------------------------------------
Apache2buddy.pl report for server:
Settings considered for this report:
[ !! ] *** LOW UPTIME ***.
[ @@ ] The following recommendations may be misleading - apache has been restarted within the last 24 hours.
Your server's physical RAM: 7976 MB
Remaining Memory after other services considered: 937 MB
Apache's MaxRequestWorkers directive: 512 <--------- Current Setting
Apache MPM Model: prefork
Largest Apache process (by memory): 10 MB
[ !! ] Your MaxRequestWorkers setting is too high.
Your recommended MaxRequestWorkers setting (based on available memory) is between 81 and 91. <------- Acceptable Range (10% of MAX)
Max potential memory usage: 5217 MB
Percentage of TOTAL RAM allocated to Apache: 65.42 %
Percentage of REMAINING RAM allocated to Apache: 556.59 %
--------------------------------------------------------------------------------
A log file entry has been made in: /var/log/apache2buddy.log for future reference.
Last 5 entries:
2019/12/19 07:37:28 Uptime: "0d 02h 26m 52s" Model: "Prefork" Memory: "7976 MB" MaxRequestWorkers: "512" Recommended: "352" Smallest: "9.81 MB" Avg: "10.28 MB" Largest: "12.35 MB" Highest Pct Remaining RAM: "145.16%" (79.28% TOTAL RAM)
2019/12/20 07:06:41 Uptime: "0d 23h 19m 11s" Model: "Prefork" Memory: "7976 MB" MaxRequestWorkers: "512" Recommended: "91" Smallest: "9.73 MB" Avg: "9.82 MB" Largest: "10.19 MB" Highest Pct Remaining RAM: "556.59%" (65.42% TOTAL RAM)
Location Table:
CREATE TABLE `locations` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`device_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Device Associated with Location',
`driver_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Driver associated with the Device',
`packet_type` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '1=Login\\n2=Heartbeat\\n3=Ping\\n4=Alarm',
`latlng` point DEFAULT NULL COMMENT 'Longitude, Latitude',
`lng` decimal(10,7) NOT NULL DEFAULT '0.0000000' COMMENT 'Longitude',
`lat` decimal(10,7) NOT NULL DEFAULT '0.0000000' COMMENT 'Latitude',
`device_time` datetime DEFAULT NULL,
`server_time` datetime DEFAULT NULL,
`imei` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`satellite` tinyint(3) unsigned NOT NULL DEFAULT '0',
`speed` tinyint(3) unsigned NOT NULL DEFAULT '0',
`acc` tinyint(3) unsigned NOT NULL DEFAULT '0',
`heading` smallint(5) unsigned NOT NULL DEFAULT '0',
`gsm_mcc` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Mobile Country Code',
`gsm_mnc` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Mobile Network Code',
`gsm_lac` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Location Area Code',
`gsm_cid` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Cell Tower ID',
`gsm_signal` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'GSM Signal Percentage',
`battery_level` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT 'Battery Level Percentage',
`alarm_code` varchar(5) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Alarm Code sent by GPS Device',
`raw_data` varchar(300) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`raw_json` varchar(3000) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '0=Not Active\\n1=Active\\n2=Deleted',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
KEY `locations_device_id_index` (`device_id`),
KEY `locations_status_index` (`status`),
KEY `locations_created_at_index` (`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
Trips Table
CREATE TABLE `trips` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`device_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'Device Associated with Trip',
`last_location_id` bigint(20) NOT NULL DEFAULT '0' COMMENT 'Last Location associated with the Trip Date',
`trip_date` date NOT NULL,
`items` longtext COLLATE utf8mb4_unicode_ci COMMENT 'Trips with points',
`points` longtext COLLATE utf8mb4_unicode_ci COMMENT 'Received points',
`is_place` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT 'When enabled, Need to get places',
`is_fetch` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT 'When enabled, Need to fetch points from locations table',
`status` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '0=Not Active\\n1=Active\\n2=Deleted',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `trips_device_id_index` (`device_id`),
KEY `trips_trip_date_index` (`trip_date`),
KEY `trips_is_place_index` (`is_place`),
KEY `trips_is_fetch_index` (`is_fetch`),
KEY `trips_status_index` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
Schema critique
Lat/lng: We are planning to implement Geo-fence, so thought we require Points for Geo spacial search so kept this field. We have not implemented it, if thats not required we will remove that.
BIGINT: Devices will be growing. But at present only 400 devices. Hope we can use small int at present.
raw Will remove both fields
updated_at we never used
created_at to generate trip for the current date we use that while in select
status I dont know about composite index I will try to implement it.