nginx系列--(一)--调试环境搭建

辅助脚本:

#!/bin/bash
mkdir -p $(pwd)/nginxhome
# 生成 Makefile,--prefix need a absolute path --with-stream表示要包括stream模块
auto/configure --prefix=$(pwd)/nginxhome --with-stream
#	lsof -i tcp:10086  && fuser -k 10086/tcp ||true
# 定义 Makefile 的路径
MAKEFILE="Makefile"
OBJS_MAKEFILE="objs/Makefile"# 检查 Makefile 是否存在
if [ ! -f "$MAKEFILE" ]; thenecho "Makefile not found!"exit 1
fi# 检查 objs/Makefile 是否存在
if [ ! -f "$OBJS_MAKEFILE" ]; thenecho "objs/Makefile not found!"exit 1
fi# 创建一个临时文件来存储修改后的内容
TEMP_FILE=$(mktemp)# 替换 objs/Makefile 中的 CFLAGS
while IFS= read -r line; doif [[ "$line" == CFLAGS* ]]; thenecho "CFLAGS = -pipe -O0 -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g" >> "$TEMP_FILE"elseecho "$line" >> "$TEMP_FILE"fi
done < "$OBJS_MAKEFILE"# 替换原 objs/Makefile
mv "$TEMP_FILE" "$OBJS_MAKEFILE"# 创建一个临时文件来存储修改后的内容
TEMP_FILE=$(mktemp)# 读取 Makefile,找到并删除原有的 clean 命令
while IFS= read -r line; doif [[ "$line" == "clean:" ]]; then# 跳过原来的 clean 规则read -rcontinuefi# 替换 $(MAKE)line=${line/\$(MAKE)/\$(MAKE) CFLAGS=\"\$(CFLAGS)\"}# 保留其他行echo "$line" >> "$TEMP_FILE"
done < "$MAKEFILE"# 插入新的 clean 规则和 all 目标
{echo ""echo "CFLAGS = -O0 -g"echo ""echo "clean:"echo -e "\tfind objs -type f \( -name '*.o' -o -name '*.d' -o -name '*.so' -o -name '*.a' \) -exec rm -f {} +"echo -e "\trm -rf nginxhome/*"echo ""echo -e "all: build install\n\ndefault:\tall"echo -e "nginx:\tbuild install"
} >> "$TEMP_FILE"# 替换原 Makefile
mv "$TEMP_FILE" "$MAKEFILE"sync
echo "Makefile updated successfully."
make all CFLAGS="-O0 -g"

sudo fuser -k 10086/tcp #杀掉占用10086端口的进程

最终makefile:


default:	build.PHONY:	default cleanbuild:lsof -i tcp:10086  && fuser -k 10086/tcp ||true   #这是自己加的 $(MAKE) CFLAGS="$(CFLAGS)" -f objs/Makefile       #这是自己修改的的 install:$(MAKE) CFLAGS="$(CFLAGS)" -f objs/Makefile installmodules:$(MAKE) CFLAGS="$(CFLAGS)" -f objs/Makefile modulesupgrade:/home/cser/work/code/nginx/nginxhome/sbin/nginx -tkill -USR2 `cat /home/cser/work/code/nginx/nginxhome/logs/nginx.pid`sleep 1test -f /home/cser/work/code/nginx/nginxhome/logs/nginx.pid.oldbinkill -QUIT `cat /home/cser/work/code/nginx/nginxhome/logs/nginx.pid.oldbin`.PHONY:	build install modules upgradeCFLAGS = -O0 -gclean:  find objs -type f \( -name '*.o' -o -name '*.d' -o -name '*.so' -o -name '*.a' \) -exec rm -f {} +rm -rf nginxhome/*all: build install #这是自己加的 default:	all #这是自己加的 
nginx:	build install #这是自己加的 

1:配置

 #!!!一定要用绝对路径,这里设置安装路径,makefile中会用到
auto/configure --prefix=/home/cser/work/code/nginx/nginxhome

2:修改makefile:1-修改clean;2:添加all;3:修改default;4:修改$(MAKE),因为默认的build/install目标是没有用到CFLAGS,所以命令行传递给makefile脚本的CFLAGS会不起作用

笔记:all需要包括build 和install,clion要求makefile含有all,并且会调用clean删除文件,而默认的则是删除所有文件,不好,所以需要我们手动修改clean目标

clean:#find objs -type f \( -name '*.o' -o -name '*.a' -o -name '*.so' -o -name '*.lo' -o -name '*.la' -o -name '*.out' \) -exec rm -rf {} +find objs -type f -name '*.o' -exec rm -f {} +
.PHONY: default clean
.PHONY:	build install modules upgrade
all: build install
default: all#修改$(MAKE)
旧:
build:$(MAKE) -f objs/Makefile
新:
build:$(MAKE) CFLAGS="$(CFLAGS)" -f objs/Makefile  #!!!CFLAGS="xx",记得加双引号

3:make并关闭优化

make CFLAGS="-O0" CXXFLAGS="-O0"

4:然后重新load makefile project !!!这一步非常重要。可以点击图标或者tool->makefile->relaod makefile project

在这里插入图片描述

5:修改配置。

笔记:通过下面三项设置之后我们修改代码,clion可以自动重新编译;

笔记:启动以后可以 curl localhost:10086 检测nginx是否启动成功

5-1:要修改target为makefile中的target,这样每次构建的时候就会make 这个target,我们需要all,即我们需要build和install。

5-2:构建完之后我们还需要指定一个可运行程序,这个程序是我们–prefix指定的目录下的nginx程序,不能是objs目录下的nginx

5-3:修改端口,默认是80端口,因为1024以下的端口需要特权,root模式启动clion需要重新激活很麻烦,所以改成10086

(笔记:如果printf没有立即输出,可以用fflush(stdout);强制刷新)

vim /path/to/config 
#这个path可以随便,因为我们会通过命令行参数-c指定配置文件
#listen       80; 改成 listen       10086;

完整配置如下:


#user  nobody;
worker_processes  1;#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;#pid        logs/nginx.pid;events {worker_connections  1024;
}http {  #!!!!nginx是根据这个模块名来调用不同的模块来解析这个配置,如果是http_abc,nginx就会调用http_abc模块来解析这个块include       mime.types;default_type  application/octet-stream;#log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '#                  '$status $body_bytes_sent "$http_referer" '#                  '"$http_user_agent" "$http_x_forwarded_for"';#access_log  logs/access.log  main;sendfile        on;#tcp_nopush     on;#keepalive_timeout  0;keepalive_timeout  65;#gzip  on;server {listen       10086;server_name  localhost;#charset koi8-r;#access_log  logs/host.access.log  main;location / {root   html;index  index.html index.htm;}location /hello {alias html;index  index.html index.htm;}#error_page  404              /404.html;# redirect server error pages to the static page /50x.html#error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}# proxy the PHP scripts to Apache listening on 127.0.0.1:80##location ~ \.php$ {#    proxy_pass   http://127.0.0.1;#}# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000##location ~ \.php$ {#    root           html;#    fastcgi_pass   127.0.0.1:9000;#    fastcgi_index  index.php;#    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;#    include        fastcgi_params;#}# deny access to .htaccess files, if Apache's document root# concurs with nginx's one##location ~ /\.ht {#    deny  all;#}}# another virtual host using mix of IP-, name-, and port-based configuration##server {#    listen       8000;#    listen       somename:8080;#    server_name  somename  alias  another.alias;#    location / {#        root   html;#        index  index.html index.htm;#    }#}# HTTPS server##server {#    listen       443 ssl;#    server_name  localhost;#    ssl_certificate      cert.pem;#    ssl_certificate_key  cert.key;#    ssl_session_cache    shared:SSL:1m;#    ssl_session_timeout  5m;#    ssl_ciphers  HIGH:!aNULL:!MD5;#    ssl_prefer_server_ciphers  on;#    location / {#        root   html;#        index  index.html index.htm;#    }#}}
stream {# 转发到后端服务server {listen 10087;  # 监听 10087 端口proxy_pass 127.0.0.1:10088;  # 转发到 10088 端口,我们写了一个程序监听10088端口}
}

5-4:指定命令行参数,包括两个:1:关闭后台运行,不关则nginx会以守

护进程方式运行,无法用cliondebug;2:设置配置文件路径。总的启动参数如下:

 -c /home/cser/work/code/nginx/conf/nginx.conf -g "daemon off;" 

6:clion调试多进程。如果不设置,那么就无法用clion debug子进程而对请求的处理都在子进程中

1.在程序的开始处设置一个断点(注意是在父进程中)

2.转到clion的调试器控制台(带有gdb的选项卡)

在fork出子进程前,依次输入set follow-fork-mode child、set detach-on-fork off

echo “hello” | nc localhost 10088 、 ./tcp_server

备注:最好不要在gdb里用方向键上翻下翻,因为此时虚拟机特别容易莫名其妙卡死,可能是vmware的问题也可能是我电脑的问题

accept=7 client=3 upstream=11

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

tcp_server程序:作为stream的backend

收到什么就返回:msg is :x

1:发送stream请求命令

sudo apt install netcat
lsof -i tcp:10088  && fuser -k 10088/tcp  
echo "hello" | nc localhost 10088
gcc tcp_server.c -o tcp_server
./tcp_server
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define DEFAULT_PORT 10088
#define BUFFER_SIZE 1024int main(int argc, char *argv[]) {int port = DEFAULT_PORT;if (argc > 1) {port = atoi(argv[1]);}int server_fd, client_fd;struct sockaddr_in server_addr, client_addr;socklen_t client_addr_len = sizeof(client_addr);char buffer[BUFFER_SIZE];// 创建 socketif ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {perror("Socket creation failed");exit(EXIT_FAILURE);}// 设置地址和端口server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY;server_addr.sin_port = htons(port);// 绑定 socketif (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {perror("Bind failed");close(server_fd);exit(EXIT_FAILURE);}// 开始监听if (listen(server_fd, 3) < 0) {perror("Listen failed");close(server_fd);exit(EXIT_FAILURE);}printf("Server listening on port %d\n", port);// 接受客户端连接while (1) {client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_len);if (client_fd < 0) {perror("Accept failed");continue;}printf("accept a connection\n");fflush(stdout);// 读取数据ssize_t bytes_read = read(client_fd, buffer, BUFFER_SIZE);if (bytes_read > 0) {buffer[bytes_read] = '\0';  // 确保字符串结束// 构造响应char response[BUFFER_SIZE];snprintf(response, sizeof(response), "msg is : %s", buffer);printf("msg is : %s\n", buffer);fflush(stdout);// 等待用户输入printf("Press Enter to continue...\n");getchar();  // 等待用户输入// 发送响应write(client_fd, response, strlen(response));printf("send ok\n------------------------------------\n");}close(client_fd);}close(server_fd);return 0;
}

20241021 22:59 遗留问题:在哪里写回响应,是不是写回响应也是一个handler,而不是单独的函数?今天下班了。已解决,就是在handler中处理

nginx.conf


worker_processes  2;                        #开启多个子进程,单worker和多worker有些流程不一样
events {worker_connections  1024;
}http {include       mime.types;default_type  application/octet-stream;sendfile        on;#keepalive_timeout  0;keepalive_timeout  65;server {listen       10086;server_name  localhost;location / {root   html;index  index.html index.htm;           #curl localhost:10086可以debug http流程limit_except GET POST {                #主要是用来debug ngx_http_request_handlerdeny all;}}location /hello {alias html;index  index.html index.htm;}error_page   500 502 503 504  /50x.html;location = /50x.html {root   html;}}}
stream {                                        #echo "hello world" | nc localhost 10087可以dubug stream流程# 转发到后端服务server {listen 10087;  # 监听 10087 端口proxy_pass 127.0.0.1:10088;  # 转发到 10088 端口}
}

tcp_client_post.c:

用来debug:把请求行、请求头、请求体分开发送,从而可以更有效地debug http请求流程 ngxin在读取完header之后就调用ngx_http_process_request,然后当请求体数据到来时,ngxin是如何处理的。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>#define SERVER_ADDR "127.0.0.1"
#define SERVER_PORT 10086void wait_for_input(int expected) {int input;while (1) {printf("请输入 %d 继续:", expected);scanf("%d", &input);if (input == expected) break;}
}int main() {int sockfd;struct sockaddr_in server_addr;const char *request_line = "POST / HTTP/1.1\r\n";const char *request_headers = "Host: localhost\r\nContent-Length: 10\r\n\r\n";const char *request_body = "helloworld";while (1) {// 等待输入 0 开始新的连接wait_for_input(0);// 创建 socketsockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {perror("Socket 创建失败");exit(EXIT_FAILURE);}// 配置服务器地址memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(SERVER_PORT);inet_pton(AF_INET, SERVER_ADDR, &server_addr.sin_addr);// 连接服务器if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {perror("连接服务器失败");close(sockfd);continue;}printf("连接已建立。\n");// 等待输入 1 并发送请求行wait_for_input(1);send(sockfd, request_line, strlen(request_line), 0);printf("已发送请求行:\n%s", request_line);// 等待输入 2 并发送请求头wait_for_input(2);send(sockfd, request_headers, strlen(request_headers), 0);printf("已发送请求头:\n%s", request_headers);// 等待输入 3 并发送请求体wait_for_input(3);send(sockfd, request_body, strlen(request_body), 0);printf("已发送请求体:\n%s", request_body);// 接收并打印服务器响应printf("等待服务器响应...\n");char buffer[1024];int received = recv(sockfd, buffer, sizeof(buffer) - 1, 0);if (received > 0) {buffer[received] = '\0';printf("服务器响应:\n%s\n", buffer);} else {printf("未收到服务器响应或连接已关闭。\n");}// 关闭连接close(sockfd);printf("------------------\n");}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/462896.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt/C++地图导航app/支持qml/手机运行/输入起点终点规划路径/模拟轨迹移动

一、前言说明 搞Qt地图开发这块&#xff0c;随着研究的深入&#xff0c;用户的需求变化&#xff0c;最近又需要在手机上运行&#xff0c;由于本地图组件依赖浏览器控件&#xff0c;而手机安卓上的Qt并没有带qwebengine控件&#xff0c;怎么办呢&#xff0c;不断的努力验证下&a…

使用VS Code 安装VUE.js开发环境的搭建并创建第一个项目

初步掌握VUE.js开发环境的搭建并创建第一个项目的操作方法和实验步骤 题目 安装Visual Studio Code。安装VS Code汉化插件。安装Vue官方支持插件。使用VS Code运行第一个HTML页面。安装Node.js并验证其版本。验证npm版本。配置npm的下载镜像源。配置Yarn的下载镜像源。使用Vi…

记本地第一次运行seatunnel示例项目

前置 静态源码编译通过&#xff1a;https://blog.csdn.net/u011924665/article/details/143372464 参考 seatunnel官方的开发环境搭建文档&#xff1a;https://seatunnel.incubator.apache.org/zh-CN/docs/2.3.5/contribution/setup 安装scala 下载scala 去官网下载&…

Maven下载安装配置(环境、本地仓库、阿里云、jdk、idea)(Win11)

目录 Maven3.9.9工具参考下载安装配置环境变量配置验证是否安装完成本地仓库位置存放配置阿里云镜像加速配置jdk版本 配置 idea Maven3.9.9 工具 系统&#xff1a;Windows 11 环境&#xff1a;JDK-8 软件&#xff1a;IDEA-2024.2.1 参考 本人写的《JDK安装与环境配置&#…

袁庭新陕西理工大学演讲——AIGC时代面临的机遇与挑战

大家好&#xff0c;我是袁庭新。分享一篇我在陕西理工大学给计算机专业、人工智能专业和网络工程专业的演讲内容。 各位计算机学院的小伙伴们&#xff0c;大家好啊&#xff01;欢迎各位来到今天的分享会&#xff0c;非常荣幸能在这里和大家相聚。今天在这里&#xff0c;我要与大…

以客户为导向在开源 AI 智能名片 2 + 1 链动模式 S2B2C 商城小程序内容创作中的实践与价值

摘要&#xff1a;本文深入探讨了在开源 AI 智能名片 2 1 链动模式 S2B2C 商城小程序相关内容创作中以客户为导向的方法和意义。阐述了如何在创作过程中通过与客户对话和转换客户视角来优化内容&#xff0c;以提升该小程序在市场中的竞争力和用户接受度。 一、引言 在数字化商…

QT——TCP网络调试助手

目录 一.项目展示 ​编辑 二.开发流程 三.QTcpServer、QTcpSocket、QUdpSocket类的学习 1.QTcpServer服务端 2.QTcpSocket客户端 3.Udp通信 四.网络调试助手 1.首先我们实现当用户选择不同协议类型时不同的UI组件如何切换 2.实现打开/关闭按键图片的切换 方式一&…

【CSS3】css开篇基础(5)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

C++学习路线(数据库部分)二

类型 整形类型 整数类型是数据库中最基本的数据类型。标准SQL中支持INTEGER和SMALLINT这两种数据类型。MySQL数据库除了支持这两种类型以外&#xff0c;还扩展支持了TINYINT、MEDIUMINT和BIGINT。下表从不同整数类型的字节数、取值范围等方面进行对比。 类型名称后面的小括号…

IDEA中通义灵码的使用技巧

大家好&#xff0c;我是 V 哥。在日常写代码的过程中&#xff0c;通过 AI 工具辅助开发已是当下程序员惯用的方式&#xff0c;V 哥在使用了众多的 AI 工具后&#xff0c;多数情况下&#xff0c;选择通义灵码来辅助开发&#xff0c;尤其是解释代码和生成单元测试功能甚是好用&am…

Docker篇(实际应用)

目录 一、MySQL 部署 1. 拉取 MySQL 镜像 2. 查看镜像 3. 创建 MySQL 容器 4. 进入 MySQL 容器,登陆 MySQL 5. 远程登陆 MySQL 6. 查看容器 IP 地址 二、tomcat 部署 1. 拉取 tomcat 镜像 2. 创建 tomcat 容器 3. 搭建 Tomcat 服务并部署 web 应用 三、Nginx 部署 …

Darknet 连接教程

本篇文章仅供学习&#xff0c;严禁用于非法用途。 1&#xff0c;前言&#xff1a; 首先明确一点&#xff0c;Darknet真没那么神奇&#xff0c;虽然有些技术文章的确很有水平&#xff0c;对于前端学习&#xff0c;软件开发以及PHP和一些服务器端维护都有许多文章&#xff0c;但…

江协科技STM32学习- P33 实验-软件I2C读写MPU6050

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

Hadoop生态圈框架部署(四)- Hadoop完全分布式部署

文章目录 前言一、Hadoop完全分布式部署&#xff08;手动部署&#xff09;1. 下载hadoop2. 上传安装包2. 解压hadoop安装包3. 配置hadoop配置文件3.1 虚拟机hadoop1修改hadoop配置文件3.1.1 修改 hadoop-env.sh 配置文件3.3.2 修改 core-site.xml 配置文件3.3.3 修改 hdfs-site…

立刻解决 gcc: error: unrecognized argument in option ‘-mabi=aapcs-linux’

unrecognized argument in option ‘-mabiaapcs-linux’ Linux 主线支持的硬件较少&#xff0c;一般是第三方开源&#xff08; Linaro/Yocto &#xff09;或者硬件厂商提供定制的嵌入式 Linux 如果确认主线支持自己的硬件&#xff0c;可以从 https://www.kernel.org/ 获取指定…

「Mac畅玩鸿蒙与硬件23」鸿蒙UI组件篇13 - 自定义组件的创建与使用

自定义组件可以帮助开发者实现复用性强、逻辑清晰的界面模块。通过自定义组件,鸿蒙应用能够提高代码的可维护性,并简化复杂布局的构建。本篇将介绍如何创建自定义组件,如何向组件传递数据,以及如何在不同页面间复用这些组件。 关键词 自定义组件复用组件属性传递组件通信组…

Windows版 nginx安装,启动,目录解析,常用命令

Windows版 nginx安装&#xff0c;启动&#xff0c;目录解析&#xff0c;常用命令 一级目录二级目录三级目录 1. 下载2. 启动方式一&#xff1a;方式二&#xff1a; 3. 验证是否启动4. 安装目录解析5. 常用命令 一级目录 二级目录 三级目录 1. 下载 官网下载&#xff1a;ngi…

Oracle视频基础1.3.7练习

1.3.7 看oracle是否启动构造一个pfile:boobooke.ora看spfilewilson内容修改alert log file里拷贝的参数内容&#xff0c;创建一个pfile boobooke.ora用新创建的pfile启动数据库&#xff0c;并创建新的spfile:spfilebbk.ora启动数据库&#xff0c;监听&#xff0c;看新的进程解…

【LeetCode】每日一题 2024_11_2 使两个整数相等的位更改次数(位运算/模拟)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;使两个整数相等的位更改次数 代码与解题思路 先读题&#xff1a; 题目要我们把 n 这个数字转换成 k 这个数字&#xff0c;但是只能是二进制位 1 转换成 0 纯模拟的解法&#xff1a; f…

鸿蒙生态下开发挑战-鸿蒙低代码开发工具展望及优势

鸿蒙生态下开发挑战 在鸿蒙生态下开发时&#xff0c;开发者可能会遇到多方面的挑战&#xff0c;这些挑战主要涉及开发工具、技术难度、生态竞争以及市场定位等方面。以下是对这些挑战的详细分析&#xff1a; 一、开发工具不完善 尽管鸿蒙系统的开发工具DevEco Studio在逐步完…