OpenNJet如何做到让用户永远在线

前言

最近看到了国内开源的一个名为OpenNJet的项目,有一个响亮的口号:“下一代云原生应用引擎”。
image.png

一下子就被吸引到了。

image.png

先看下官方对OpenNJet的介绍:
OpenNJet 应用引擎基于 NGINX 面向互联网和云原生应用提供的运行时组态服务程序,作为底层引擎,OpenNJet 实现了NGINX 云原生功能增强、安全加固和代码重构,利用动态加载机制可以实现不同的产品形态,如Web服务器、流媒体服务器、负载均衡、代理(Proxy)、应用中间件、API网关、消息队列等产品形态等等。
OpenNJet 在云原生架构中作为数据平面,除了提供南北向通信网关的功能以外,还提供了服务网格中东西向通信能力。在原有功能基础上增加了透明流量劫持、熔断、遥测与故障注入等新功能特性。

看完这段介绍大概了解到了,这个OpenNjet应用引擎是基于NGINX开发的。经过我的对比分析,确实是这样子的,如果你用过NGINX,亲自编译过NGINX你会发现OpenNJet的编译选项和NGINX的都是很像的。源代码也是类似,所以对于接触过NGINX的同学来说上手OpenNJet是很容易的。

官方给了你选择OpenNJet的理由:
image.png

因为我算是稍微深度使用过NGINX的用户,我用NGINX做过线上的代理服务,部署过web服务,在流媒体领域还做过RTMP服务,还做过静态资源库。

我是对OpenNJet的动态配置这个模块很感兴趣的,首先说一下我使用Nginx时遇到的缺陷:Nginx确实是存在你如果想修改了配置,必须要重启服务,这也是领人头疼的,一旦运行起来,如果重新启动一下,会造成很多额外的损失。

因为我是做流媒体领域的。所以也想体验一下,OpenNjet如何接入流媒体服务。

所以本文会针对动态配置和流媒体服务两点做一些探索和研究。

Ubuntu通过deb包安装

这种方式就是拿来即用。使用是没有问题的,当然了如果你要做个测试或者当做一个服务去使用的话,完全没有问题。但是你想进行二次开发的话,这个方式就行不通了,需要自己从头到尾编译一遍。

先看一个比较简单的安装方法:

1、下载deb安装包:
https://gitee.com/njet-rd/njet/releases

2、下载好的:

zhenghui@zh-pc:build_njet$ ls -l njet_2.0.1-1~ubuntu.18.04~bionic_amd64.deb 
-rwxrwxrwx 1 root root 19230036  424 23:31 njet_2.0.1-1~ubuntu.18.04~bionic_amd64.deb
zhenghui@zh-pc:build_njet$ 

3、使用dpkg进行安装

zhenghui@zh-pc:build_njet$ sudo dpkg -i  njet_2.0.1-1~ubuntu.18.04~bionic_amd64.deb 
[sudo] zhenghui 的密码: 
正在选中未选择的软件包 njet。
(正在读取数据库 ... 系统当前共安装有 706429 个文件和目录。)
准备解压 njet_2.0.1-1~ubuntu.18.04~bionic_amd64.deb  ...
正在解压 njet (2.0.1) ...
正在设置 njet (2.0.1) ...
Created symlink /etc/systemd/system/multi-user.target.wants/njet.service → /lib/systemd/system/njet.service.
正在处理用于 libc-bin (2.35-0ubuntu3.7) 的触发器 ...
zhenghui@zh-pc:build_njet$ 

看着一句:Created symlink /etc/systemd/system/multi-user.target.wants/njet.service → /lib/systemd/system/njet.service

说明已经在系统中创建了service的方式。

安装位置:

zhenghui@zh-pc:njet$ pwd
/usr/local/njet
zhenghui@zh-pc:njet$ 
zhenghui@zh-pc:njet$ ls
client_body_temp  conf  data  fastcgi_temp  html  lib  logs  lualib  modules  proxy_temp  sbin  scgi_temp  uwsgi_temp
zhenghui@zh-pc:njet$ 

功能体验

1、如何控制njet服务

njet做到了系统的services里,可以使用systemctl命令来控制服务,这一点对于使用者来说很方便。
然后就可以启动njet服务和关闭njet服务了:

systemctl start njet #启动服务
systemctl stop njet #停止服务

查看是否启动成功

zhenghui@zh-pc:soft$ sudo netstat -ntpl |grep njet
tcp        0      0 0.0.0.0:8081            0.0.0.0:*               LISTEN      580250/njet: copilo 
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      580233/njet: master 
zhenghui@zh-pc:soft$ 

浏览器输入:http://127.0.0.1:8080/

出现如下界面既成功:
image.png

停止服务:

zhenghui@zh-pc:build_njet$ sudo systemctl stop njet
zhenghui@zh-pc:build_njet$ 
zhenghui@zh-pc:build_njet$ sudo netstat -ntpl |grep njet
zhenghui@zh-pc:build_njet$ 

还提供了其他的一些指令:
1、显示帮助信息 : njet -h
2、 启动:njet -p /tmpr/njet/   -c conf/njet.conf
常见启动参数:

  • -p 指定prefix配置文件路径,不指定,默认/etc/njet
  • -c 指定配置文件,不指定,默认njet.conf
  • -e 指定error 日志文件

3、测试配置信息是否有错误: njet -t
4、显示版本:njet -v
5、显示编译阶段的参数: njet -V
6、快速停止:njet -s stop 或者 kill -TERM {进程id}
7、优雅停止服务:njet -s quit  或者 kill -QUIT {进程id}
8、重新加载配置:njet -s reload 或者 kill -HUP {进程id}

2、如何部署自己的web网站

我的安装目录在:/usr/local/njet
/usr/local/njet/html就是网站的默认root根目录。

root根目录的位置也是可以修改的:

vim /usr/local/njet/conf/njet.conf

1 worker_processes auto;
2 
3 cluster_name njet;
4 node_name node1;
5 
6 error_log logs/error.log error;
7 
8 helper ctrl /usr/local/njet/modules/njt_helper_ctrl_module.so /usr/local/njet/conf/njet_ctrl.conf;
9 helper broker /usr/local/njet/modules/njt_helper_broker_module.so;
10 
11 load_module /usr/local/njet/modules/njt_http_split_clients_2_module.so;
12 load_module /usr/local/njet/modules/njt_agent_dynlog_module.so;
13 load_module /usr/local/njet/modules/njt_http_dyn_bwlist_module.so;
14 load_module /usr/local/njet/modules/njt_dyn_ssl_module.so;
15 load_module /usr/local/njet/modules/njt_http_vtsc_module.so;
16 load_module /usr/local/njet/modules/njt_http_location_module.so;
17 #load_module /usr/local/njet/modules/njt_http_lua_module.so;
18 #load_module /usr/local/njet/modules/njt_http_modsecurity_module.so;
19 #load_module /usr/local/njet/modules/njt_http_dyn_modsecurity_module.so;
20 
21 
22 events {
23     worker_connections  1024;
24 }
25 
26 
27 http {
28     include mime.types;
29     access_log off;
30     vhost_traffic_status_zone;
31     #lua_package_path "$prefix/lualib/lib/?.lua;/usr/local/njet/modules/?.lua;;";
32     #lua_package_cpath "$prefix/lualib/clib/?.so;;";
33     server {
34         #modsecurity on;
35         #modsecurity_rules_file /usr/local/njet/conf/modsec/main.conf;
36 
37         listen       8080;
38         location / {
39            root html;
40         }
41     }
42 
43 }

还可以看到默认端口是listen = 8080

第一步:可以找到自己的web资源,放到你的安装目录下的html中
例如我放了一个admin的目录:

zhenghui@zh-pc:njet$ cd html/
zhenghui@zh-pc:html$ ls
50x.html  50x.html.dpkg-new  50x.html.dpkg-tmp  admin  index.html  index.html.dpkg-new  index.html.dpkg-tmp
zhenghui@zh-pc:html$ pwd
/usr/local/njet/html
zhenghui@zh-pc:html$ 

此时自己的网站就部署成功了
image.png

就这么简单,只需要一步。

3、使用API接口管理配置

njet提供了API接口来动态操作这一切,例如启动成功后,如果你什么都没改,会有一个8081的端口,可以访问:http://127.0.0.1:8081/doc/swagger/ 进入 swagger的api文档。

image.png

4、使用GUI管理配置

还提供了gui来控制

访问:
http://127.0.0.1:8081/doc/gui/

image.png

5、http_log模块动态配置

我们使用最简单的方式:http://127.0.0.1:8081/doc/gui/

打开web后,点开http_log模块:

此时accessLogOn为false,说明当前没有开启日志。可以看到当前logs目录下的文件状态

image.png

我们选择为true:

此时还没保存,可以看到logs的状态

image.png

我们修改一下,然后保存:
image.png

可以看到njet并没有重启,我们还在一直操作。

可以使用tail -f实时监控日志,看看日志是不是真的生效了:
image.png

此时可以刷新下web界面,可以看到日志哗啦啦的就出来了。
image.png

这就是动态配置的作用,不必重启。

编译安装

如果你是ubuntu需要安装如下:

sudo apt-get install gcc g++ make cmake libpcre2-dev libpcre3-dev libssl-dev zlib1g-dev perl m4  libtool  automake autoconf vim-common unzip  libcap2-bin

1、下载地址:

国内推荐从gitee上下载:https://gitee.com/njet-rd
国外推荐从github上下载:https://github.com/OpenNJet/OpenNJet

当然了,如果你会魔法的话,也建议直接从github上。

我下载的是目前最新版2.1.0:

root@zhenghui-tx:~/soft/build_OpenNJet# ls -l njet-v2.1.0.tar.gz
-rw-r--r-- 1 root root 29065901 Apr 24 09:13 njet-v2.1.0.tar.gz
root@zhenghui-tx:~/soft/build_OpenNJet#

解压:

root@zhenghui-tx:~/soft/build_OpenNJet#
root@zhenghui-tx:~/soft/build_OpenNJet# tar -zxvf njet-v2.1.0.tar.gz

解压后:

root@zhenghui-tx:~/soft/build_OpenNJet# cd njet-v2.1.0/
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0#
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# ls
auto   build_cc.sh   build_lua.sh  CHANGES.ru  configure  doc         Dockerfile.ubuntu  img      luajit  man      modules_dynamic  njet_sidecar.conf  README     repos    src
build  build_k8s.sh  CHANGES       conf        contrib    Dockerfile  html               LICENSE  lualib  modules  modules_static   NOTICE             README.md  scripts
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0#

初次拿到一个陌生的需要编译的项目,肯定是先查看README.xx文档,然后就是看编译配置脚本:

root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# ./configure --help

  --help                             print this message

  --prefix=PATH                      set installation prefix
  --sbin-path=PATH                   set njet binary pathname
  --modules-path=PATH                set modules path
  --conf-path=PATH                   set njet.conf pathname
  --error-log-path=PATH              set error log pathname
  --pid-path=PATH                    set njet.pid pathname
  --lock-path=PATH                   set njet.lock pathname

  --user=USER                        set non-privileged user for
                                     worker processes
  --group=GROUP                      set non-privileged group for
                                     worker processes

  --build=NAME                       set build name
  --builddir=DIR                     set build directory

  --with-select_module               enable select module
  --without-select_module            disable select module
  --with-poll_module                 enable poll module
  --without-poll_module              disable poll module

  --with-threads                     enable thread pool support

  --with-file-aio                    enable file AIO support

  --without-quic_bpf_module          disable njt_quic_bpf_module

  --without-dynamic-pool             disable njet dynamic pool usage

  --with-http_ssl_module             enable njt_http_ssl_module
  --with-http_v2_module              enable njt_http_v2_module
  --with-http_v3_module              enable njt_http_v3_module
  --with-http_realip_module          enable njt_http_realip_module
  --with-http_addition_module        enable njt_http_addition_module
  --with-http_xslt_module            enable njt_http_xslt_module
  --with-http_xslt_module=dynamic    enable dynamic njt_http_xslt_module
  --with-http_image_filter_module    enable njt_http_image_filter_module
  --with-http_image_filter_module=dynamic
                                     enable dynamic njt_http_image_filter_module
  --with-http_geoip_module           enable njt_http_geoip_module
  --with-http_geoip_module=dynamic   enable dynamic njt_http_geoip_module
  --with-http_sub_module             enable njt_http_sub_module
  --with-http_dav_module             enable njt_http_dav_module
  --with-http_flv_module             enable njt_http_flv_module
  --with-http_mp4_module             enable njt_http_mp4_module
  --with-http_gunzip_module          enable njt_http_gunzip_module
  --with-http_gzip_static_module     enable njt_http_gzip_static_module
  --with-http_auth_request_module    enable njt_http_auth_request_module
  --with-http_random_index_module    enable njt_http_random_index_module
  --with-http_secure_link_module     enable njt_http_secure_link_module
  --with-http_degradation_module     enable njt_http_degradation_module
  --with-http_slice_module           enable njt_http_slice_module
  --with-http_stub_status_module     enable njt_http_stub_status_module

  --without-http_charset_module      disable njt_http_charset_module
  --without-http_gzip_module         disable njt_http_gzip_module
  --without-http_ssi_module          disable njt_http_ssi_module
  --without-http_userid_module       disable njt_http_userid_module
  --without-http_access_module       disable njt_http_access_module
  --without-http_auth_basic_module   disable njt_http_auth_basic_module
  --without-http_mirror_module       disable njt_http_mirror_module
  --without-http_autoindex_module    disable njt_http_autoindex_module
  --without-http_geo_module          disable njt_http_geo_module
  --without-http_map_module          disable njt_http_map_module
  --without-http_split_clients_module disable njt_http_split_clients_module
  --without-http_referer_module      disable njt_http_referer_module
  --without-http_rewrite_module      disable njt_http_rewrite_module
  --without-http_proxy_module        disable njt_http_proxy_module
  --without-http_fastcgi_module      disable njt_http_fastcgi_module
  --without-http_uwsgi_module        disable njt_http_uwsgi_module
  --without-http_scgi_module         disable njt_http_scgi_module
  --without-http_grpc_module         disable njt_http_grpc_module
  --without-http_memcached_module    disable njt_http_memcached_module
  --without-http_limit_conn_module   disable njt_http_limit_conn_module
  --without-http_limit_req_module    disable njt_http_limit_req_module
  --without-http_empty_gif_module    disable njt_http_empty_gif_module
  --without-http_browser_module      disable njt_http_browser_module
  --without-http_upstream_hash_module
                                     disable njt_http_upstream_hash_module
  --without-http_upstream_ip_hash_module
                                     disable njt_http_upstream_ip_hash_module
  --without-http_upstream_least_conn_module
                                     disable njt_http_upstream_least_conn_module
  --without-http_upstream_random_module
                                     disable njt_http_upstream_random_module
  --without-http_upstream_keepalive_module
                                     disable njt_http_upstream_keepalive_module
  --without-http_upstream_zone_module
                                     disable njt_http_upstream_zone_module

  --with-http_perl_module            enable njt_http_perl_module
  --with-http_perl_module=dynamic    enable dynamic njt_http_perl_module
  --with-perl_modules_path=PATH      set Perl modules path
  --with-perl=PATH                   set perl binary pathname

  --http-log-path=PATH               set http access log pathname
  --http-client-body-temp-path=PATH  set path to store
                                     http client request body temporary files
  --http-proxy-temp-path=PATH        set path to store
                                     http proxy temporary files
  --http-fastcgi-temp-path=PATH      set path to store
                                     http fastcgi temporary files
  --http-uwsgi-temp-path=PATH        set path to store
                                     http uwsgi temporary files
  --http-scgi-temp-path=PATH         set path to store
                                     http scgi temporary files

  --without-http                     disable HTTP server
  --without-http-cache               disable HTTP cache

  --with-mail                        enable POP3/IMAP4/SMTP proxy module
  --with-mail=dynamic                enable dynamic POP3/IMAP4/SMTP proxy module
  --with-mail_ssl_module             enable njt_mail_ssl_module
  --without-mail_pop3_module         disable njt_mail_pop3_module
  --without-mail_imap_module         disable njt_mail_imap_module
  --without-mail_smtp_module         disable njt_mail_smtp_module

  --with-stream                      enable TCP/UDP proxy module
  --with-stream=dynamic              enable dynamic TCP/UDP proxy module
  --with-stream_ssl_module           enable njt_stream_ssl_module
  --with-stream_realip_module        enable njt_stream_realip_module
  --with-stream_geoip_module         enable njt_stream_geoip_module
  --with-stream_geoip_module=dynamic enable dynamic njt_stream_geoip_module
  --with-stream_ssl_preread_module   enable njt_stream_ssl_preread_module
  --without-stream_limit_conn_module disable njt_stream_limit_conn_module
  --without-stream_access_module     disable njt_stream_access_module
  --without-stream_geo_module        disable njt_stream_geo_module
  --without-stream_map_module        disable njt_stream_map_module
  --without-stream_split_clients_module
                                     disable njt_stream_split_clients_module
  --without-stream_return_module     disable njt_stream_return_module
  --without-stream_set_module        disable njt_stream_set_module
  --without-stream_upstream_hash_module
                                     disable njt_stream_upstream_hash_module
  --without-stream_upstream_least_conn_module
                                     disable njt_stream_upstream_least_conn_module
  --without-stream_upstream_random_module
                                     disable njt_stream_upstream_random_module
  --without-stream_upstream_zone_module
                                     disable njt_stream_upstream_zone_module

  --with-google_perftools_module     enable njt_google_perftools_module
  --with-cpp_test_module             enable njt_cpp_test_module

  --add-module=PATH                  enable external module
  --add-dynamic-module=PATH          enable dynamic external module

  --with-compat                      dynamic modules compatibility

  --with-ntls                        enable NTLS support

  --with-cc=PATH                     set C compiler pathname
  --with-cpp=PATH                    set C preprocessor pathname
  --with-cc-opt=OPTIONS              set additional C compiler options
  --with-ld-opt=OPTIONS              set additional linker options
  --with-cpu-opt=CPU                 build for the specified CPU, valid values:
                                     pentium, pentiumpro, pentium3, pentium4,
                                     athlon, opteron, sparc32, sparc64, ppc64

  --without-pcre                     disable PCRE library usage
  --with-pcre                        force PCRE library usage
  --with-pcre=DIR                    set path to PCRE library sources
  --with-pcre-opt=OPTIONS            set additional build options for PCRE
  --with-pcre-conf-opt=OPTIONS       set additional configure options for PCRE
  --with-pcre-jit                    build PCRE with JIT compilation support
  --without-pcre2                    do not use PCRE2 library

  --with-zlib=DIR                    set path to zlib library sources
  --with-zlib-opt=OPTIONS            set additional build options for zlib
  --with-zlib-asm=CPU                use zlib assembler sources optimized
                                     for the specified CPU, valid values:
                                     pentium, pentiumpro

  --with-libatomic                   force libatomic_ops library usage
  --with-libatomic=DIR               set path to libatomic_ops library sources

  --with-openssl=DIR                 set path to OpenSSL library sources
  --with-openssl-opt=OPTIONS         set additional build options for OpenSSL

  --with-debug                       enable debug logging

root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0#

可以看到有各种选项,各种功能的开关。

我们再来看一下nginx源码的编译配置:

root@zhenghui-tx:~/soft/nginx-1.23.4# ./configure --help

  --help                             print this message

  --prefix=PATH                      set installation prefix
  --sbin-path=PATH                   set nginx binary pathname
  --modules-path=PATH                set modules path
  --conf-path=PATH                   set nginx.conf pathname
  --error-log-path=PATH              set error log pathname
  --pid-path=PATH                    set nginx.pid pathname
  --lock-path=PATH                   set nginx.lock pathname

  --user=USER                        set non-privileged user for
                                     worker processes
  --group=GROUP                      set non-privileged group for
                                     worker processes

  --build=NAME                       set build name
  --builddir=DIR                     set build directory

  --with-select_module               enable select module
  --without-select_module            disable select module
  --with-poll_module                 enable poll module
  --without-poll_module              disable poll module

  --with-threads                     enable thread pool support

  --with-file-aio                    enable file AIO support

  --with-http_ssl_module             enable ngx_http_ssl_module
  --with-http_v2_module              enable ngx_http_v2_module
  --with-http_realip_module          enable ngx_http_realip_module
  --with-http_addition_module        enable ngx_http_addition_module
  --with-http_xslt_module            enable ngx_http_xslt_module
  --with-http_xslt_module=dynamic    enable dynamic ngx_http_xslt_module
  --with-http_image_filter_module    enable ngx_http_image_filter_module
  --with-http_image_filter_module=dynamic
                                     enable dynamic ngx_http_image_filter_module
  --with-http_geoip_module           enable ngx_http_geoip_module
  --with-http_geoip_module=dynamic   enable dynamic ngx_http_geoip_module
  --with-http_sub_module             enable ngx_http_sub_module
  --with-http_dav_module             enable ngx_http_dav_module
  --with-http_flv_module             enable ngx_http_flv_module
  --with-http_mp4_module             enable ngx_http_mp4_module
  --with-http_gunzip_module          enable ngx_http_gunzip_module
  --with-http_gzip_static_module     enable ngx_http_gzip_static_module
  --with-http_auth_request_module    enable ngx_http_auth_request_module
  --with-http_random_index_module    enable ngx_http_random_index_module
  --with-http_secure_link_module     enable ngx_http_secure_link_module
  --with-http_degradation_module     enable ngx_http_degradation_module
  --with-http_slice_module           enable ngx_http_slice_module
  --with-http_stub_status_module     enable ngx_http_stub_status_module

  --without-http_charset_module      disable ngx_http_charset_module
  --without-http_gzip_module         disable ngx_http_gzip_module
  --without-http_ssi_module          disable ngx_http_ssi_module
  --without-http_userid_module       disable ngx_http_userid_module
  --without-http_access_module       disable ngx_http_access_module
  --without-http_auth_basic_module   disable ngx_http_auth_basic_module
  --without-http_mirror_module       disable ngx_http_mirror_module
  --without-http_autoindex_module    disable ngx_http_autoindex_module
  --without-http_geo_module          disable ngx_http_geo_module
  --without-http_map_module          disable ngx_http_map_module
  --without-http_split_clients_module disable ngx_http_split_clients_module
  --without-http_referer_module      disable ngx_http_referer_module
  --without-http_rewrite_module      disable ngx_http_rewrite_module
  --without-http_proxy_module        disable ngx_http_proxy_module
  --without-http_fastcgi_module      disable ngx_http_fastcgi_module
  --without-http_uwsgi_module        disable ngx_http_uwsgi_module
  --without-http_scgi_module         disable ngx_http_scgi_module
  --without-http_grpc_module         disable ngx_http_grpc_module
  --without-http_memcached_module    disable ngx_http_memcached_module
  --without-http_limit_conn_module   disable ngx_http_limit_conn_module
  --without-http_limit_req_module    disable ngx_http_limit_req_module
  --without-http_empty_gif_module    disable ngx_http_empty_gif_module
  --without-http_browser_module      disable ngx_http_browser_module
  --without-http_upstream_hash_module
                                     disable ngx_http_upstream_hash_module
  --without-http_upstream_ip_hash_module
                                     disable ngx_http_upstream_ip_hash_module
  --without-http_upstream_least_conn_module
                                     disable ngx_http_upstream_least_conn_module
  --without-http_upstream_random_module
                                     disable ngx_http_upstream_random_module
  --without-http_upstream_keepalive_module
                                     disable ngx_http_upstream_keepalive_module
  --without-http_upstream_zone_module
                                     disable ngx_http_upstream_zone_module

  --with-http_perl_module            enable ngx_http_perl_module
  --with-http_perl_module=dynamic    enable dynamic ngx_http_perl_module
  --with-perl_modules_path=PATH      set Perl modules path
  --with-perl=PATH                   set perl binary pathname

  --http-log-path=PATH               set http access log pathname
  --http-client-body-temp-path=PATH  set path to store
                                     http client request body temporary files
  --http-proxy-temp-path=PATH        set path to store
                                     http proxy temporary files
  --http-fastcgi-temp-path=PATH      set path to store
                                     http fastcgi temporary files
  --http-uwsgi-temp-path=PATH        set path to store
                                     http uwsgi temporary files
  --http-scgi-temp-path=PATH         set path to store
                                     http scgi temporary files

  --without-http                     disable HTTP server
  --without-http-cache               disable HTTP cache

  --with-mail                        enable POP3/IMAP4/SMTP proxy module
  --with-mail=dynamic                enable dynamic POP3/IMAP4/SMTP proxy module
  --with-mail_ssl_module             enable ngx_mail_ssl_module
  --without-mail_pop3_module         disable ngx_mail_pop3_module
  --without-mail_imap_module         disable ngx_mail_imap_module
  --without-mail_smtp_module         disable ngx_mail_smtp_module

  --with-stream                      enable TCP/UDP proxy module
  --with-stream=dynamic              enable dynamic TCP/UDP proxy module
  --with-stream_ssl_module           enable ngx_stream_ssl_module
  --with-stream_realip_module        enable ngx_stream_realip_module
  --with-stream_geoip_module         enable ngx_stream_geoip_module
  --with-stream_geoip_module=dynamic enable dynamic ngx_stream_geoip_module
  --with-stream_ssl_preread_module   enable ngx_stream_ssl_preread_module
  --without-stream_limit_conn_module disable ngx_stream_limit_conn_module
  --without-stream_access_module     disable ngx_stream_access_module
  --without-stream_geo_module        disable ngx_stream_geo_module
  --without-stream_map_module        disable ngx_stream_map_module
  --without-stream_split_clients_module
                                     disable ngx_stream_split_clients_module
  --without-stream_return_module     disable ngx_stream_return_module
  --without-stream_set_module        disable ngx_stream_set_module
  --without-stream_upstream_hash_module
                                     disable ngx_stream_upstream_hash_module
  --without-stream_upstream_least_conn_module
                                     disable ngx_stream_upstream_least_conn_module
  --without-stream_upstream_random_module
                                     disable ngx_stream_upstream_random_module
  --without-stream_upstream_zone_module
                                     disable ngx_stream_upstream_zone_module

  --with-google_perftools_module     enable ngx_google_perftools_module
  --with-cpp_test_module             enable ngx_cpp_test_module

  --add-module=PATH                  enable external module
  --add-dynamic-module=PATH          enable dynamic external module

  --with-compat                      dynamic modules compatibility

  --with-cc=PATH                     set C compiler pathname
  --with-cpp=PATH                    set C preprocessor pathname
  --with-cc-opt=OPTIONS              set additional C compiler options
  --with-ld-opt=OPTIONS              set additional linker options
  --with-cpu-opt=CPU                 build for the specified CPU, valid values:
                                     pentium, pentiumpro, pentium3, pentium4,
                                     athlon, opteron, sparc32, sparc64, ppc64

  --without-pcre                     disable PCRE library usage
  --with-pcre                        force PCRE library usage
  --with-pcre=DIR                    set path to PCRE library sources
  --with-pcre-opt=OPTIONS            set additional build options for PCRE
  --with-pcre-jit                    build PCRE with JIT compilation support
  --without-pcre2                    do not use PCRE2 library

  --with-zlib=DIR                    set path to zlib library sources
  --with-zlib-opt=OPTIONS            set additional build options for zlib
  --with-zlib-asm=CPU                use zlib assembler sources optimized
                                     for the specified CPU, valid values:
                                     pentium, pentiumpro

  --with-libatomic                   force libatomic_ops library usage
  --with-libatomic=DIR               set path to libatomic_ops library sources

  --with-openssl=DIR                 set path to OpenSSL library sources
  --with-openssl-opt=OPTIONS         set additional build options for OpenSSL

  --with-debug                       enable debug logging

root@zhenghui-tx:~/soft/nginx-1.23.4#

如果你深入使用过nginx或者自己编译过nginx的话,是可以直接上手OpenNJet 。

我在编译的时候,比较喜欢创建一个脚本,在脚本里写构建的脚本代码,这样有助于后期查看:

root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0#
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# touch build.sh
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0#

如果初次不太了解的话,执行最简单的语法,先让项目跑起来即可,后期再根据自己需求增加编译选项:

我比较喜欢使用–prefix选项,因为这样比较方便自己维护安装的目录,如果每一个项目都安装到系统的/lib或/usr等系统目录中,可能会造成乱象。编译自己其他项目时可能会出错,也很难排查。
用过C和C++的朋友应该都懂这个,其实就是lib库的链接问题,include引用错路径的问题等等。

 ./configure --prefix=`pwd`/_install

庆幸的是,官方提供的build的脚本,我们可以直接使用:

./build_cc.sh conf

如下结果就是成功了:
image.png

执行make:
image.png

报错:

make[3]: Entering directory '/root/soft/build_OpenNJet/njet-v2.1.0/auto/lib/tongsuo'
gcc  -I. -Iinclude -Icrypto/ec/curve448/arch_32 -Icrypto/ec/curve448 -fPIC -m64 -Wa,--noexecstack -Wall -O3 -DDEBUG_UNUSED -DPEDANTIC -pedantic -Wno-long-long -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wswitch -Wsign-compare -Wshadow -Wformat -Wtype-limits -Wundef -Werror -Wmissing-prototypes -Wstrict-prototypes -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DAESNI_ASM -DVPAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM -DOPENSSLDIR="\"/root/soft/build_OpenNJet/njet-v2.1.0/auto/lib/tongsuo/.openssl/ssl\"" -DENGINESDIR="\"/root/soft/build_OpenNJet/njet-v2.1.0/auto/lib/tongsuo/.openssl/lib/engines-1.1\"" -DNDEBUG  -MMD -MF crypto/ec/curve448/f_generic.d.tmp -MT crypto/ec/curve448/f_generic.o -c -o crypto/ec/curve448/f_generic.o crypto/ec/curve448/f_generic.c
crypto/ec/curve448/f_generic.c:21:27: error: argument 1 of type 'uint8_t[56]' {aka 'unsigned char[56]'} with mismatched bound [-Werror=array-parameter=]
   21 | void gf_serialize(uint8_t serial[SER_BYTES], const gf x, int with_hibit)
      |                   ~~~~~~~~^~~~~~~~~~~~~~~~~
In file included from crypto/ec/curve448/f_generic.c:12:
crypto/ec/curve448/field.h:65:28: note: previously declared as 'uint8_t *' {aka 'unsigned char *'}
   65 | void gf_serialize(uint8_t *serial, const gf x, int with_highbit);
      |                   ~~~~~~~~~^~~~~~
cc1: all warnings being treated as errors
make[3]: *** [Makefile:2830: crypto/ec/curve448/f_generic.o] Error 1
make[3]: Leaving directory '/root/soft/build_OpenNJet/njet-v2.1.0/auto/lib/tongsuo'
make[2]: *** [Makefile:176: all] Error 2
make[2]: Leaving directory '/root/soft/build_OpenNJet/njet-v2.1.0/auto/lib/tongsuo'
make[1]: *** [objs/Makefile:5184: auto/lib/tongsuo/.openssl/include/openssl/ssl.h] Error 2
make[1]: Leaving directory '/root/soft/build_OpenNJet/njet-v2.1.0'
make: *** [Makefile:10: build] Error 2
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0#
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0#
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# find ./ -name "f_generic.c"
./auto/lib/tongsuo/crypto/ec/curve448/f_generic.c
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0#
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# vim ./auto/lib/tongsuo/crypto/ec/curve448/f_generic.c
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# vim ./auto/lib/tongsuo/crypto/ec/curve448/f_generic.c + 21
2 files to edit
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# vim ./auto/lib/tongsuo/crypto/ec/curve448/f_generic.c +21
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# 

可以看到.h和.c文件中的参数类型不匹配,一个是数组,一个是指针:
image.png

特意查了一下,openssl是有提交补丁的:
https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=7217decc7c454eec4a6d4ce163ac44b4558fe03b

image.png

修改之后的:

root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0#
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# vim ./auto/lib/tongsuo/crypto/ec/curve448/f_generic.c +21
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0#
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0#
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# grep -nr "gf_serialize" ./auto/lib/tongsuo/crypto/ec/curve448/
grep: ./auto/lib/tongsuo/crypto/ec/curve448/f_generic.o: binary file matches
./auto/lib/tongsuo/crypto/ec/curve448/f_generic.c:21://void gf_serialize(uint8_t serial[], const gf x, int with_hibit)
./auto/lib/tongsuo/crypto/ec/curve448/f_generic.c:22:void gf_serialize(uint8_t *serial, const gf x, int with_hibit)
grep: ./auto/lib/tongsuo/crypto/ec/curve448/curve448.o: binary file matches
./auto/lib/tongsuo/crypto/ec/curve448/curve448.c:311:    gf_serialize(enc, x, 1);
./auto/lib/tongsuo/crypto/ec/curve448/curve448.c:444:    gf_serialize(out, x1, 1);
./auto/lib/tongsuo/crypto/ec/curve448/curve448.c:468:    gf_serialize(out, q->y, 1);
./auto/lib/tongsuo/crypto/ec/curve448/field.h:65:void gf_serialize(uint8_t *serial, const gf x, int with_highbit);
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0#

再次make:
image.png

又报了错误,报错如下:

gcc  -I. -Iinclude -fPIC -m64 -Wa,--noexecstack -Wall -O3 -DDEBUG_UNUSED -DPEDANTIC -pedantic -Wno-long-long -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wswitch -Wsign-compare -Wshadow -Wformat -Wtype-limits -Wundef -Werror -Wmissing-prototypes -Wstrict-prototypes -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DAESNI_ASM -DVPAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM -DOPENSSLDIR="\"/root/soft/build_OpenNJet/njet-v2.1.0/auto/lib/tongsuo/.openssl/ssl\"" -DENGINESDIR="\"/root/soft/build_OpenNJet/njet-v2.1.0/auto/lib/tongsuo/.openssl/lib/engines-1.1\"" -DNDEBUG  -MMD -MF ssl/s3_cbc.d.tmp -MT ssl/s3_cbc.o -c -o ssl/s3_cbc.o ssl/s3_cbc.c
In file included from /usr/include/string.h:535,
                 from include/internal/constant_time.h:14,
                 from ssl/s3_cbc.c:10:
In function 'memcpy',
    inlined from 'ssl3_cbc_digest_record' at ssl/s3_cbc.c:379:13:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:29:10: error: '__builtin___memcpy_chk' offset [64, 128] is out of the bounds [0, 13] [-Werror=array-bounds]
   29 |   return __builtin___memcpy_chk (__dest, __src, __len,
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   30 |                                  __glibc_objsize0 (__dest));
      |                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make[3]: *** [Makefile:6149: ssl/s3_cbc.o] Error 1
make[3]: Leaving directory '/root/soft/build_OpenNJet/njet-v2.1.0/auto/lib/tongsuo'
make[2]: *** [Makefile:176: all] Error 2
make[2]: Leaving directory '/root/soft/build_OpenNJet/njet-v2.1.0/auto/lib/tongsuo'
make[1]: *** [objs/Makefile:5184: auto/lib/tongsuo/.openssl/include/openssl/ssl.h] Error 2
make[1]: Leaving directory '/root/soft/build_OpenNJet/njet-v2.1.0'
make: *** [Makefile:10: build] Error 2

很无奈,一些编译问题,不得不让我放弃了这一条选择。
这是我的编译机的一些基本信息:

root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# 
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# uname -a
Linux zhenghui-tx 5.15.0-79-generic #86-Ubuntu SMP Mon Jul 10 16:07:21 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# 
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# 
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# 
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.4.0-1ubuntu1~22.04' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) 
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# 
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.4.0-1ubuntu1~22.04' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) 
root@zhenghui-tx:~/soft/build_OpenNJet/njet-v2.1.0# 

最终编译安装这个环境以失败告终,这个编译的问题我认为是官方必须要搞定的,也提了相关Issues 感兴趣的可以看一下: https://github.com/OpenNJet/OpenNJet/issues/4

官方人员也是很积极的回复了,说之后的版本会提升tongsuo到8.4.0:
image.png

很期待下一个版本,下个版本出来后,我再来深入探究一下。

如何使用docker搭建一个开发环境

对于一个玩C&C++的人来说,这一项技能是必须的,因为开发环境用docker最简单了,还可以隔离宿主机的各种环境,互不干扰。

1、下载源码
国内推荐从gitee上下载:https://gitee.com/njet-rd
国外推荐从github上下载:https://github.com/OpenNJet/OpenNJet

2、因为njet本身就提供了Dockerfile,所以天生就支持了:
image.png

构建docker镜像:

docker build -t njet_main:v1.0 .

执行后如果能查出来说明构建成功了:

zhenghui@zh-pc:njet$ sudo docker  images |grep njet
njet_main               v1.0      784bed5f0897   2 minutes ago   520MB
zhenghui@zh-pc:njet$ 

运行:

docker run -v `pwd`:/njet_main njet_main:v1.0 /bin/bash -c "cd /njet_main && ./build_cc.sh conf make"

其实可以分成2个步骤:
1、后台一直跑着这个docker即可:

zhenghui@zh-pc:njet$ sudo docker run -td -v `pwd`:/njet_main njet_main:v1.0 /bin/bash 
3c626ddc91eee718ef8044238626a28616e614b7db39245ef3321cdf1e64bdba
zhenghui@zh-pc:njet$ 

2、需要的时候进入:

zhenghui@zh-pc:njet$ sudo docker ps -a
CONTAINER ID   IMAGE                COMMAND                   CREATED         STATUS                     PORTS                                                                                                                                                                                                                                                     NAMES
3c626ddc91ee   njet_main:v1.0       "/bin/bash"               2 minutes ago   Up 2 minutes

3、进入docker
3c626ddc91ee ID就是进入docker的必要条件之一:

zhenghui@zh-pc:njet$ sudo docker exec -it 3c626ddc91ee /bin/bash
[root@3c626ddc91ee /]# 
[root@3c626ddc91ee /]# 

下面就是进入docker后的:

[root@3c626ddc91ee /]# cd /njet_main/
[root@3c626ddc91ee njet_main]# 
[root@3c626ddc91ee njet_main]# pwd
/njet_main
[root@3c626ddc91ee njet_main]# ls
CHANGES  CHANGES.ru  Dockerfile  Dockerfile.ubuntu  LICENSE  Makefile  NOTICE  README  README.md  auto  build  build_cc.sh  build_k8s.sh  build_lua.sh  conf  configure  contrib  doc  html  img  luajit  lualib  man  modules  modules_dynamic  modules_static  njet_sidecar.conf  objs  repos  scripts  src
[root@3c626ddc91ee njet_main]# 
[root@3c626ddc91ee njet_main]# 

4、编译

cd /njet_main 

./build_cc.sh conf make

docker还是比较方便的,用官方提供的Dockerfile生成的docker镜像,一下子就成功了,对于开发者来说,或者二次开发者进行二次开发来说很方便。起码不让你为了编译环境不一致而烦恼。

开发时可以采用“宿主机编辑代码”+“Docker上编译代码”这个方案。
因为我平时工作时也是这样做的,很方便。

总结

本次体验OpenNjet好像开盲盒一样,一个一个的惊喜扑面而来。我从2个角度来总结一下对OpenNjet的初体验。

1、使用者角度

  • 上手快:对于使用者来说,如果使用者用过NGINX的话,用njet可以说是秒秒钟上手,真的很容易。因为一些相关的配置可以很完美的和NGINX融合,也可以看作为向下兼容。对于用户来说,我认为上手快就是一大特点。
  • 易用:为什么说是易用呢,因为njet提供了多种配置njet的方式,还增加了动态配置的功能,拿API接口来说吧,这一点就打败了市场上很多普通web服务器,当然了njet也不能和普通的web服务器做对比,因为njet的口号是:让用户永远在线!
  • 第三方用户友好:因为有动态配置,再加上njet的口号:让用户永远在线!很明显的可以体验出来,对于第三方用户是无感的,企业修改一些配置,第三方用户如何还在进行着操作,此时是不受影响的,没有丝毫感觉。本文也体现njet的愿景:让用户永远在线!
  • 可以基于Docker部署比较灵活;
  • 可以支持HTTP/3;

2、开发者角度

  • 开发环境灵活:提供了多种开发环境的支持,这一点比较灵活。例如我本次想使用系统直接编译开发呢,结果失败了,就换了一种docker的方式,就一下子成功了。这就是灵活性。
  • 二次开发简单:因为njet提供了一系列的API接口,如果要对接到自己的dev系统中,是很简单的事情,直接调API接口即可,针对DevOps很方便。
  • 完全适配NGINX用户:因为njet是基于NGINX做的二次开发,所以njet完全适配NGINX,所以完全适配NGINX用户。对NGINX做过二次开发的开发者来说,这一点也是值得肯定的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何根据配置动态生成Spring的Bean?

一、问题解析 在 Spring 应用中,根据运行时的配置(比如数据库配置、配置文件、配置中心等)动态生成 Spring Bean 是一种常见需求,特别是在面对多环境配置或者需要根据不同条件创建不同实例时。 Spring 提供了几种方式来实现这一需…

spice common模块

库分为三部分libspice-common.a,libspice-common-client.a,libspice-common-server.a。 1、libspice-common.a工程编译代码 # # libspice-common # spice_common_sources [ agent.c, agent.h, backtrace.c, backtrace.h, canvas_utils.c, canvas_utils.h, demarsha…

sql编写规范(word原件)

编写本文档的目的是保证在开发过程中产出高效、格式统一、易阅读、易维护的SQL代码。 1 编写目的 2 SQL书写规范 3 SQL编写原则 软件全套资料获取进主页或者本文末个人名片直接获取。

高德地图在vue3项目中使用:实现画矢量图、编辑矢量图

使用高德地图实现画多边形、矩形、圆&#xff0c;并进行编辑保存和回显。 1、准备工作 参考高德地图官网&#xff0c;进行项目key申请&#xff0c;链接: 准备 2、项目安装依赖 npm i amap/amap-jsapi-loader --save3、地图容器 html <template><!-- 绘制地图区域…

GNSS 地球自转改正算例分析

文章目录 Part.I IntroductionPart.II 由地球自转引起的误差的概念和改正方法Chap.I 误差概念Chap.II 改正方法 Part.II 算例分析Chap.I 基础数据Chap.II 计算过程 AppendixReference Part.I Introduction 为了更好地理解 地球自转改正&#xff0c;本文将介绍一个算例。 Part.…

手动交互式选点提取三维点云轮廓边界线 附python代码

一种新的三维点云轮廓边界提取方案: 1 手动选择一个边界或者其附近的点 2 自动搜索临近区域,并找到附近的平面和进行平面分割 3 提取平面的交点 4 该交点就是点云的轮廓边界点,把它往两边延展,就是完整的点云轮廓边界 import open3d as o3d import numpy as np import …

Java模块化系统:引领代码革命与性能飞跃

JDK工程结构的问题 在说Java模块化系统之前&#xff0c;先来说说Java9之前的JDK在工程结构上的问题&#xff0c;从JDK本身的问题说起&#xff0c;Java从1996年发布第一版到2017年发布Java9&#xff0c;中间经历了近20年的时间&#xff0c;在这期间发布了无数个大大小小的版本用…

RESTFul风格设计和实战

四、RESTFul风格设计和实战 4.1 RESTFul风格概述 4.1.1 RESTFul风格简介 RESTful&#xff08;Representational State Transfer&#xff09;是一种软件架构风格&#xff0c;用于设计网络应用程序和服务之间的通信。它是一种基于标准 HTTP 方法的简单和轻量级的通信协议&#x…

YAML如何操作Kubernetes核心对象

Pod Kubernetes 最核心对象Pod Pod 是对容器的“打包”&#xff0c;里面的容器&#xff08;多个容器&#xff09;是一个整体&#xff0c;总是能够一起调度、一起运行&#xff0c;绝不会出现分离的情况&#xff0c;而且 Pod 属于 Kubernetes&#xff0c;可以在不触碰下层容器的…

存储或读取时转换JSON数据

一、 数据库类型 二、使用Hutool工具 存储时将数据转换为JSON数据 获取时将JSON数据转换为对象 发现问题&#xff1a; 原本数据对象是Address 和 Firend但是转换完成后数据变成了JSONArray和JSONObject 三、自定义TypeHandler继承Mybatis的BaseTypeHandler处理器 package …

Feign 和 OpenFeign 的区别

Feign 和 OpenFeign 都是用来进行服务间调用的客户端库&#xff0c;它们旨在简化HTTP API客户端的编写过程&#xff0c;使得编写对外部服务的接口就像调用本地方法一样简单。尽管它们有相似之处&#xff0c;但也存在一些关键差异&#xff1a; 归属和演进&#xff1a; Feign 最初…

硬件设计计划与APQP

硬件设计的关键节点: 大的里程碑milestone分为: Kickoff->A Samples->做出第一批B样总成件->B Samples/OTS->C Samples->PPAP->SOP 具体到硬件,A/B/C sample阶段,又可细分为: 关键器件选型&硬件系统方案设计原理图绘制PCB LayoutA_BOM输出PCB制板…

3. 深度学习笔记--优化函数

深度学习——优化器算法Optimizer详解&#xff08;BGD、SGD、MBGD、Momentum、Adagrad、Adadelta、RMSprop、Adam、Nadam、AdaMax、AdamW &#xff09; 0. GD &#xff08;梯度下降&#xff09; Gradient Descent&#xff08;梯度下降&#xff09;是一种迭代优化算法&#xf…

FreeRTOS内存管理(1-20)

FreeRTOS内存管理简介 在使用FreeRTOS创建任务&#xff0c;队列&#xff0c;信号量等对象时&#xff0c;一般都提供两种方法 1&#xff1a;动态创建任务&#xff08;方法&#xff09;自动地从FreeRTOS管理的内存堆中申请创建对象所需要的内存&#xff0c;并且在删除对象后可以…

九州金榜|孩子沉迷于网络:家庭教育的挑战与对策

随着时代的进步&#xff0c;科技的发展&#xff0c;网络现在成为了我们日常生活不可分割的一部分。然而&#xff0c;随着网络的普及也出现了一些列的问题&#xff0c;其中孩子沉迷于网络就是当前家长最为关心的问题&#xff0c;对于这种情况的发生&#xff0c;家庭教育就显得尤…

Linux主机重启后报错:[FAILED] Failed to start Switch Root.

一、问题描述 某次云主机因计费问题&#xff0c;导致批量重启&#xff0c;重启后发现某台云主机竟进入紧急救援模式&#xff08;emergency模式&#xff09;&#xff0c;如下所示&#xff1a; 二、原因及处理 1&#xff09;原因&#xff1a;加载根分区失败&#xff0c;导致无…

Libcity笔记:原子文件

1 介绍 Libcity中的数据以原子文件的形式存在 2 原子文件类别 对于不同的交通预测任务&#xff0c;可能用到不同的原子文件&#xff0c;同一个数据集不一定包含全部六种原子文件 网格数据需要按照先行后列的顺序遍历OD数据需要按照先起点后终点的顺序遍历 2.1 geo 存储地理…

Netty 实现dubbo rpc

一、RPC 的基本介绍 RPC (Remote Procedure Call) 远程过程调用&#xff0c;是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序&#xff0c;而程序员无需额外的为这个交互编程。也就是说可以达到两个或者多个应用程序部署在不同的服务器上&…

OpenCV 入门(七)—— 身份证识别

OpenCV 入门系列&#xff1a; OpenCV 入门&#xff08;一&#xff09;—— OpenCV 基础 OpenCV 入门&#xff08;二&#xff09;—— 车牌定位 OpenCV 入门&#xff08;三&#xff09;—— 车牌筛选 OpenCV 入门&#xff08;四&#xff09;—— 车牌号识别 OpenCV 入门&#xf…

德国韦纳WENAROLL滚压刀,液压缸,滚光刀,挤压刀,滚轧刀

德国韦纳WENAROLL滚压刀,液压缸&#xff0c;滚光刀,挤压刀&#xff0c;滚轧刀&#xff08;百度一下&#xff0c;西安尚融&#xff09; 德国韦纳&#xff08;WENAROLL&#xff09;的滚压刀、液压缸、滚光刀、挤压刀和滚轧刀在工业领域享有很高的声誉&#xff0c;这些产品因其高…