顾乔芝士网

持续更新的前后端开发技术栈

linux服务器开发之网关服务器的实现

什么是网关服务器

初学linux服务器开发时,我们的服务器是很简单的,只需要一个程序完成与客户端的连接,接收客户端数据,数据处理,向客户端发送数据。
但是在处理量很大的情况下,一台机器不能满足我们的需求,此时我们应该怎么办。
我们可以将服务端的任务分摊到多台机器上完成,见下图

从图中可见,此时整个服务端主要分为了三部分。

网关服务器:负责连接客户端与逻辑服务器,在两者间完成数据转发,使用负载均衡算法保证每个逻辑服务器的工作量均衡,以及进行数据加密。

记一次集群内无可用http服务问题排查

前一阵子发现服务会有偶发的服务不可用的情况,记录一下这个问题的排查过程。

现象是这样的:每天到了某个时间点,就会出现服务不稳定的情况,偶发接口调不通。

线上业务使用了lvs-nginx-tomcat三层结构,首先查看tomcat监控,没有什么特别异常的情况,响应时间和错误码没发现有什么异常,CPU、IO等等指标也都正常。

再查看nginx上的监控,发现在某个时刻这个服务的5xx报错突增,大概7、8秒之后又恢复了。

继续在nginx服务器上找线索,发现Nginx在那个时间点会出现报错:

常用网络协议整理笔记(一)(各种网络协议名称及作用)

本文索引:

1. 网络协议整体框架

【Linux网络编程】TCP编程(tcping linux)

01. TCP概述

传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。

TCP旨在适应支持多网络应用的分层协议层次结构。 连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。TCP假设它可以从较低级别的协议获得简单的,可能不可靠的数据报服务。 原则上,TCP应该能够在从硬线连接到分组交换或电路交换网络的各种通信系统之上操作。

C语言网络编程:客户端与服务端最简单的通信模型

服务端和客户端

TCP利用封包和解包解决“粘包”问题

一、TCP粘包现象

what?

TCP是个“流”协议,即没有边界。由于这个特性以及实际的网络情况,在进行数据传输时假设我们连续调用send分别发送两段数据data1和data2,在接收端有以下几种代表性的情况:

Linux并发IO详解(下)(linux并发执行命令的方式)

Demo

本部分代码实现参考可能是最接地气的 I/O 多路复用小结 (
https://mengkang.net/726.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io)

阻塞式网络编程接口

详解协程的实现与原理剖析(协程 原理)

协程的起源

问题:协程存在的原因?协程能够解决哪些问题?

在我们现在CS,BS开发模式下,服务器的吞吐量是一个很重要的参数。其实吞吐量是IO处理时间加上业务处理。为了简单起见,比如,客户端与服务器之间是长连接的,客户端定期给服务器发送心跳包数据。客户端发送一次心跳包到服务器,服务器更新该新客户端状态的。心跳包发送的过程,业务处理时长等于IO读取(RECV系统调用)加上业务处理(更新客户状态)。吞吐量等于1s业务处理次数。

Linux网络编程(第一部分)涉及的代码

套接字定义:

它是通过标准的 UNIX 文件描述符和其他的程序通讯的一个方法。

Linux网络编程——端口复用(多个套接字绑定同一个端口)

实际上,默认的情况下,如果一个网络应用程序的一个套接字 绑定了一个端口( 占用了 8000 ),这时候,别的套接字就无法使用这个端口( 8000 ), 验证例子如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 
int main(int argc, char *argv[])
{
	int sockfd_one;
	int err_log;
	sockfd_one = socket(AF_INET, SOCK_DGRAM, 0); //创建UDP套接字one
	if(sockfd_one < 0)
	{
	perror("sockfd_one");
	exit(-1);
	}
 
	// 设置本地网络信息
	struct sockaddr_in my_addr;
	bzero(&my_addr, sizeof(my_addr));
	my_addr.sin_family = AF_INET;
	my_addr.sin_port = htons(8000);		// 端口为8000
	my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
 
	// 绑定,端口为8000
	err_log = bind(sockfd_one, (struct sockaddr*)&my_addr, sizeof(my_addr));
	if(err_log != 0)
	{
		perror("bind sockfd_one");
		close(sockfd_one);		
		exit(-1);
	}
 
	int sockfd_two;
	sockfd_two = socket(AF_INET, SOCK_DGRAM, 0);  //创建UDP套接字two
	if(sockfd_two < 0)
	{
		perror("sockfd_two");
		exit(-1);
	}
 
	// 新套接字sockfd_two,继续绑定8000端口,绑定失败
	// 因为8000端口已被占用,默认情况下,端口没有释放,无法绑定
	err_log = bind(sockfd_two, (struct sockaddr*)&my_addr, sizeof(my_addr));
	if(err_log != 0)
	{
		perror("bind sockfd_two");
		close(sockfd_two);		
		exit(-1);
	}
 
	close(sockfd_one);
	close(sockfd_two);
 
	return 0;
}
<< < 51 52 53 54 55 56 57 58 59 60 > >>
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言