OpenNJet产品体验丨从零部署一个炫酷的Web服务器

news2024/11/26 8:44:54

本文记录了使用OpenNJet从零部署一个Web服务器的心得体会。

OpenNJet官方网站:https://njet.org.cn/

一、基本信息

产品名称

OpenNJet

体验版本

2.1.0

体验设备

VMware16+Ubuntu18.04

体验时间

2024.4.23

体验耗时

1.5 h

二、产品信息

  • 产品简介:OpenNJet是一个云原生应用引擎,其设计目标是为互联网和云环境中的应用程序提供运行时配置和服务管理能力。该应用引擎基于NGINX构建,并对NGINX进行了云原生功能增强、安全加固和代码重构,以适应现代云环境的需求。
  • 产品类型:OpenNJet应用引擎是一个高性能、轻量级的WEB应用与代理软件。
  • 产品定位:作为云原生服务网格的数据平面,NJet具备动态配置加载、主动式健康检测、集群高可用、声明式API等多种强大功能。通过CoPliot副驾驶服务框架,在隔离控制面和数据面的情况下实现了高可扩展性。NJet应用引擎助力企业实现云原生技术的平滑升级并大幅降低IT运营成本。

三、技术特点

OpenNJet在NGINX的架构上进行了扩充,对其框架进行了改写,增加了可持久化的动态存储能力,解决了指令配置变更动态生效的关键问题,扩展了OpenNJet的应用场景。其主要的技术特点如下。

1.环境感知:OpenNJet能够根据云环境的变化进行动态调整和适配。

2.安全控制:OpenNJet提供了安全相关的功能来保护运行在其上的应用。

3.加速优化:OpenNJet可以通过各种方式优化网络性能和资源使用效率。

4.动态加载机制:OpenNJet支持不同产品形态的灵活扩展,可以快速部署并作为Web服务器、流媒体服务器、负载均衡器、代理服务器、应用中间件、API 网关、消息代理等。

5.服务网格功能:支持东西向通信、透明流量劫持、熔断、遥测与故障注入、链路追踪等功能,便于微服务架构下的服务管理和运维。

6.容器化与云原生兼容性:与云原生基础设施无缝集成,支持蓝绿发布等云原生部署策略。

此外,OpenNJet成为了开放原子开源基金会的孵化项目,受到了业界的关注和支持,并且致力于通过开源社区的方式推动技术创新和生态建设。

四、产品结构

产品结构如图1所示。

图1 产品结构图

五、产品体验

基于OpenNJet搭建一个轻量级的Web服务器

分为环境搭建安装OpenNJet以及部署Web服务器等三大部分。

5.1 环境搭建

本部分较为基础,这里引用了一些不错的文章,供大家参考。(0.5h)

5.1.1 安装VMware16虚拟机

安装步骤:最新超详细VMware虚拟机下载与安装

5.1.2 下载Ubuntu18.04镜像

下载地址:Ubuntu 18.04.6 LTS (Bionic Beaver)

5.1.3 在VMware16中配置Ubuntu18.04

配置步骤:VMwareWorkstation16与Ubuntu 18.04.6 LTS下载与安装

5.2 安装OpenNJet

本部分将阐述安装OpenNJet的详细步骤。(0.5h

参考文章:https://njet.org.cn/docs/quickstart/

5.2.1 更新软件包

  • 命令如下

Shell
sudo install upgrade

该命令用于更新ubuntu自带的软件包。

  • 截图如下(图2)

图2 更新软件包

5.2.2 安装必须的软件

  • 命令如下

Shell
sudo apt install vim
sudo apt install net-tools
sudo apt-get autoremove open-vm-tools
sudo apt-get install open-vm-tools-desktop

vim用于编辑文本,net-tools用于查看虚拟机的ip

open-vm-toolsopen-vm-tools-desktop用于设置桌面全屏,以及实现本机与虚拟机间的复制黏贴

注意】安装软件后需要重启虚拟机

5.2.3 安装需要用到的软件

  • 软件如下

gcc

g++

make

cmake

libpcre2-dev

libpcre3-dev

libssl-dev

zlib1g-dev

perl

m4  

libtool  

automake

autoconf

vim-common

unzip  

libcap2-bin

  • 命令如下

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

  • 截图如下(图3)

图3 安装需要的软件

5.2.4 添加gpg文件

  • 命令如下

Shell
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://njet.org.cn/download/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/njet.gpg
sudo chmod a+r /etc/apt/keyrings/njet.gpg

  • 截图如下(图4)

图4 添加gpg文件

5.2.5 添加apt源

  • 命令如下

Plaintext
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/njet.gpg] https://njet.org.cn/download/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/njet.list > /dev/null
sudo apt-get update

  • 截图如下(图5)

图5 添加apt源

5.2.6 安装并启动njet

  • 命令如下

Plaintext
sudo apt-get install njet
sudo systemctl start njet

  • 截图如下(图6)

图6 安装并启动njet

5.2.7 测试web服务器是否启动

  • 命令如下

Shell
curl localhost:8080/

此命令可以向localhost:8080发送GET请求,获取网页内容。

  • 截图如下(图7)

图7 使用curl命令

此时打开Firefox浏览器,在地址栏中输入localhost:8080,会出现图8所示的欢迎页面

图8 欢迎页面

至此,成功安装OpenNJet

5.3 部署WEB服务器

本部分将使用OpenNJet部署一个炫酷的Web服务器。(0.5h

参考文章:https://njet.org.cn/docs/user-guide/

5.3.1 查看conf文件

1.OpenNJet的主要配置文件为njet.conf,可以通过修改该文件来配置OpenNJet。

该文件在/usr/local/njet/conf目录下,如图9所示。

图9 njet.conf文件的路径

2.可以双击njet.conf文件查看其内容,该文件的内容如图10所示。

图10 njet.conf文件的内容

5.3.2 修改conf文件

1.修改njet.conf文件的权限,并以笔记本(gedit命令)的方式打开该文件,代码如下。

Shell
sudo apt install gedit
cd /usr/local/njet/conf
sudo chmod a+w njet.conf
gedit njet.conf

截图如图11所示。

图11 修改njet.conf文件的权限

2.修改njet.conf文件的内容,将listen的端口号修改为80,修改的文本如下。

Shell
http {
    include mime.types;
    access_log off;
    vhost_traffic_status_zone;
    #lua_package_path "$prefix/lualib/lib/?.lua;/usr/local/njet/modules/?.lua;;";
    #lua_package_cpath "$prefix/lualib/clib/?.so;;";
    server {
        #modsecurity on;       
        #modsecurity_rules_file /usr/local/njet/conf/modsec/main.conf;

        listen       80;
        location / {
           root html;
        }
    }
}

修改后的文本如图12所示。

图12 修改listen的端口号为80

3.最后保存文本并退出。

5.3.2 查看html文件

1.进入/usr/local/njet/html目录并查看index.html文件,如图13所示。

图13 index.html文件的路径

2.双击index.html文件并查看其内容,该文件的内容如图14所示。

图14 index.html文件的路径

注意到网址localhost:8080的内容就是该文件,修改这个文件即可修改localhost:8080的内容。

5.3.2 修改html文件

1.修改index.html文件的权限,并以笔记本(gedit命令)的方式打开该文件,代码如下。

Shell
cd /usr/local/njet/html
sudo chmod a+w index.html
gedit index.html

截图如图15所示。

图15 修改index.html文件的权限

2.修改index.html文件,删除原有代码并填入以下代码。(该html代码实现了一个炫酷的爱心)

更多炫酷的html代码见:https://github.com/Want595/FunnyHTML

HTML
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>heart</title>
    <style>
        canvas {
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, .2);
        }
    </style>
</head>
<body>
    <canvas id="heart" width="1920" height="947"></canvas>
    <script>
        window.requestAnimationFrame =
            window.__requestAnimationFrame ||
            window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            (function () {
                return function (callback, element) {
                    var lastTime = element.__lastTime;
                    if (lastTime === undefined) {
                        lastTime = 0;
                    }
                    var currTime = Date.now();
                    var timeToCall = Math.max(1, 33 - (currTime - lastTime));
                    window.setTimeout(callback, timeToCall);
                    element.__lastTime = currTime + timeToCall;
                };
            })();
        window.isDevice = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(((navigator.userAgent || navigator.vendor || window.opera)).toLowerCase()));
        var loaded = false;
        var init = function () {
            if (loaded) return;
            loaded = true;
            var mobile = window.isDevice;
            var koef = mobile ? 0.5 : 1;
            var canvas = document.getElementById('heart');
            var ctx = canvas.getContext('2d');
            var width = canvas.width = koef * innerWidth;
            var height = canvas.height = koef * innerHeight;
            var rand = Math.random;
            ctx.fillStyle = "rgba(0,0,0,1)";
            ctx.fillRect(0, 0, width, height);
            var heartPosition = function (rad) {
                //return [Math.sin(rad), Math.cos(rad)];
                return [Math.pow(Math.sin(rad), 3), -(15 * Math.cos(rad) - 5 * Math.cos(2 * rad) - 2 * Math.cos(3 * rad) - Math.cos(4 * rad))];
            };
            var scaleAndTranslate = function (pos, sx, sy, dx, dy) {
                return [dx + pos[0] * sx, dy + pos[1] * sy];
            };
            window.addEventListener('resize', function () {
                width = canvas.width = koef * innerWidth;
                height = canvas.height = koef * innerHeight;
                ctx.fillStyle = "rgba(0,0,0,1)";
                ctx.fillRect(0, 0, width, height);
            });
            var traceCount = mobile ? 20 : 50;
            var pointsOrigin = [];
            var i;
            var dr = mobile ? 0.3 : 0.1;
            for (i = 0; i < Math.PI * 2; i += dr) pointsOrigin.push(scaleAndTranslate(heartPosition(i), 210, 13, 0, 0));
            for (i = 0; i < Math.PI * 2; i += dr) pointsOrigin.push(scaleAndTranslate(heartPosition(i), 150, 9, 0, 0));
            for (i = 0; i < Math.PI * 2; i += dr) pointsOrigin.push(scaleAndTranslate(heartPosition(i), 90, 5, 0, 0));
            var heartPointsCount = pointsOrigin.length;

            var targetPoints = [];
            var pulse = function (kx, ky) {
                for (i = 0; i < pointsOrigin.length; i++) {
                    targetPoints[i] = [];
                    targetPoints[i][0] = kx * pointsOrigin[i][0] + width / 2;
                    targetPoints[i][1] = ky * pointsOrigin[i][1] + height / 2;
                }
            };
            var e = [];
            for (i = 0; i < heartPointsCount; i++) {
                var x = rand() * width;
                var y = rand() * height;
                e[i] = {
                    vx: 0,
                    vy: 0,
                    R: 2,
                    speed: rand() + 5,
                    q: ~~(rand() * heartPointsCount),
                    D: 2 * (i % 2) - 1,
                    force: 0.2 * rand() + 0.7,
                    f: "hsla(240," + ~~(40 * rand() + 60) + "%," + ~~(60 * rand() + 20) + "%,.3)",   //修改颜色
                    trace: []
                };
                for (var k = 0; k < traceCount; k++) e[i].trace[k] = { x: x, y: y };
            }

            var config = {
                traceK: 0.4,
                timeDelta: 0.01
            };
            var time = 0;
            var loop = function () {
                var n = -Math.cos(time);
                pulse((1 + n) * .5, (1 + n) * .5);
                time += ((Math.sin(time)) < 0 ? 9 : (n > 0.8) ? .2 : 1) * config.timeDelta;
                ctx.fillStyle = "rgba(0,0,0,.1)";
                ctx.fillRect(0, 0, width, height);
                for (i = e.length; i--;) {
                    var u = e[i];
                    var q = targetPoints[u.q];
                    var dx = u.trace[0].x - q[0];
                    var dy = u.trace[0].y - q[1];
                    var length = Math.sqrt(dx * dx + dy * dy);
                    if (10 > length) {
                        if (0.95 < rand()) {
                            u.q = ~~(rand() * heartPointsCount);
                        } else {
                            if (0.99 < rand()) {
                                u.D *= -1;
                            }
                            u.q += u.D;
                            u.q %= heartPointsCount;
                            if (0 > u.q) {
                                u.q += heartPointsCount;
                            }
                        }
                    }
                    u.vx += -dx / length * u.speed;
                    u.vy += -dy / length * u.speed;
                    u.trace[0].x += u.vx;
                    u.trace[0].y += u.vy;
                    u.vx *= u.force;
                    u.vy *= u.force;
                    for (k = 0; k < u.trace.length - 1;) {
                        var T = u.trace[k];
                        var N = u.trace[++k];
                        N.x -= config.traceK * (N.x - T.x);
                        N.y -= config.traceK * (N.y - T.y);
                    }
                    ctx.fillStyle = u.f;
                    for (k = 0; k < u.trace.length; k++) {
                        ctx.fillRect(u.trace[k].x, u.trace[k].y, 1, 1);
                    }
                }
                ctx.fillStyle = "rgba(255,255,255,1)";
                for (i = u.trace.length + 13; i--;) ctx.fillRect(targetPoints[i][0], targetPoints[i][1], 2, 2);
                window.requestAnimationFrame(loop, canvas);
            };
            loop();
        };
        var s = document.readyState;
        if (s === 'complete' || s === 'loaded' || s === 'interactive') init();
        else document.addEventListener('DOMContentLoaded', init, false);
    </script>
</body>
</html>

修改后的代码如图16所示。

图16 修改后的index.html文件

3.最后保存代码并退出。

5.3.3 重启njet服务

使用以下代码重启njet服务。

HTML
sudo systemctl stop njet
sudo systemctl start njet

截图如图17所示。

图17 重启njet

5.3.4 查看web服务器

最后打开浏览器,在地址栏中输入localhost:80,此时会出现如图18所示的炫酷页面。

图18 炫酷的页面

六、总结

很高兴受邀体验了OpenNJet开源项目,个人感觉该项目非常值得探索,感谢每一个为OpenNJet做出贡献的开发者。希望本文可以帮助小伙伴们快速入门OpenNJet,由于本人能力有限,如果有小伙伴在阅读本文时发现了BUG,欢迎提出宝贵的意见。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【13-支持向量机(SVM):Scikit-learn中的分类与回归】

文章目录 前言理解SVM核心概念SVM的优势SVM的劣势Scikit-learn中的SVM实现安装与导入数据准备SVM分类SVM回归调优与最佳实践总结前言 支持向量机(SVM)是一种强大的机器学习算法,用于解决分类、回归和异常检测问题。它的核心思想是找到一个最优超平面,使得不同类别之间的边界…

一文了解云原生应用引擎的领跑者:OpenNJet

一文了解云原生应用引擎的领跑者&#xff1a;OpenNJet 1. 什么是应用引擎2. NGINX 架构与 NJet架构的区别3. OpenNJet 编译与安装步骤3.1 配置编译环境-CentOS 编译环境配置3.2 编译代码 4. OpenNJet 的基本使用4.1 系统目录结构及功能说明4.2 基础命令 5. 快速上手-如何通过 O…

4.Docker本地镜像发布至阿里云仓库、私有仓库、DockerHub

文章目录 0、镜像的生成方法1、本地镜像发布到阿里云仓库2、本地镜像发布到私有仓库3、本地镜像发布到Docker Hub仓库 Docker仓库是集中存放镜像的地方&#xff0c;分为公共仓库和私有仓库。 注册服务器是存放仓库的具体服务器&#xff0c;一个注册服务器上可以有多个仓库&…

IP纯净度对跨境电商有什么直接影响?

IP纯净度对跨境电商具有直接且深远的影响。在跨境电商的运作中&#xff0c;IP地址扮演着至关重要的角色&#xff0c;而IP纯净度则直接关系到跨境电商的网络安全性、访问效果以及业务竞争力。 第一点&#xff0c;纯净的IP地址对于提升跨境电商的网络安全性具有关键作用&#xf…

AI项目二十:基于YOLOv8实例分割的DeepSORT多目标跟踪

若该文为原创文章&#xff0c;转载请注明原文出处。 前面提及目标跟踪使用的方法有很多&#xff0c;更多的是Deepsort方法。 本篇博客记录YOLOv8的实例分割deepsort视觉跟踪算法。结合YOLOv8的目标检测分割和deepsort的特征跟踪&#xff0c;该算法在复杂环境下确保了目标的准…

信创 | 信创产品行业有哪些?已取得了哪些进展?

信创产业是一条庞大的产业链&#xff0c;涉及IT基础设施产品&#xff08;如CPU芯片、服务器、存储、交换机、路由器等&#xff09;&#xff0c;以及基础软件、应用软件、网络安全等领域。信创产业的核心目标是建立自主可控的信息技术底层架构和标准&#xff0c;全面推进国产替代…

Models_M1

a1 Hugging Face a2 openai/whisper-large-v3 示 a3 ByteDance/Hyper-SD 示​​​​​​​ a4 OpenGVLab/InternV…

LeetCode-旋转链表

每日一题&#xff0c;很久没做链表的题了&#xff0c;今天做l一道相对简单的力扣中等难度题。 题目要求 给你一个链表的头节点 head &#xff0c;旋转链表&#xff0c;将链表每个节点向右移动 k 个位置。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], k 2 输出&…

FPGA 以太网概念简单学习

1 MAC和PHY 从硬件的角度来说&#xff0c;以太网接口电路主要由 MAC &#xff08; Media Access Control &#xff09;控制器和物理层接口 PHY&#xff08;Physical Layer &#xff0c; PHY &#xff09;两大部分构成。 MAC 指媒体访问控制子层协议&#xff0c;它和 PHY 接…

使用yolov8+QT+onnrunxtime进行开发的注意事项

1、本来想尝试做一个C的yolov8在QT5.15.2的应用&#xff1b; 因此&#xff0c;在实现这个目标的时候&#xff0c;我先用了yolov8自带的export进行导出&#xff0c;使用的代码很简单&#xff0c;如下所示&#xff1a; import os from ultralytics import YOLO# model YOLO(&q…

优卡特脸爱云一脸通智慧平台 UpLoadPic.ashx 文件上传致RCE漏洞复现

0x01 产品简介 脸爱云一脸通智慧管理平台是一套功能强大,运行稳定,操作简单方便,用户界面美观,轻松统计数据的一脸通系统。无需安装,只需在后台配置即可在浏览器登录。功能包括:系统管理中心、人员信息管理中心、设备管理中心、消费管理子系统、订餐管理子系统、水控管理…

uniapp分包,以及通过uni-simple-router进行分包

先说一下uniapp的直接分包方式&#xff0c;很简单&#xff1a; 配置分包信息 打开manifest.json源码视图&#xff0c;添加 “optimization”:{“subPackages”:true} 开启分包优化 我们在根目录下创建一个pagesA文件夹&#xff0c;用来放置需要分包的页面 然后配置路由 运行到…

OpenNMS安装

环境要求 硬件要求 Just Testing 1Minimum Server Specification 2Minimum Server Specification 2CPU2GHz dual core x86_643GHz quad core x86_64 and aboveRAM4GB (physical)16GB (physical) and aboveStorage (disk space)50-GB HDD, SSD1TB with SSD and above You can i…

Python并发编程:揭开多线程与异步编程的神秘面纱

第一章&#xff1a;并发编程导论 1.1 并发与并行概念解析 1.1.1 并发性与并行性的区别 想象一下繁忙的厨房中多位厨师同时准备不同的菜肴——即使他们共享有限的空间和资源&#xff0c;也能协同工作&#xff0c;这就是并发性的一个生动比喻。并发性意味着多个任务在同一时间…

基于 dockerfile 编写LNMP

目录 一. 环境准备 二. 部署 nginx 2.1 建立工作目录&#xff0c;并上传需要的安装包 2.2 配置 nginx.conf 文件 2.3 编写 dockerfile 2.4 构建一个新的镜像 2.5 启动一个新的容器 三. 部署MySQL 3.1 建立工作目录&#xff0c;并上传安装包 3.2 编写 Dockerfile 3.…

ROS学习笔记(14)拉普拉斯变换和PID

0.前提 近些时间在对睿抗的ROS仿真赛进行小组安排&#xff0c;对小组成员进行了一些安排&#xff0c;也要求他们以本次比赛写下自己的比赛经历博客&#xff0c;他们的培训由我来安排和负责&#xff0c;因此我得加吧油&#xff0c;起码保证我的进度得快过他们&#xff0c;才能安…

源码编译安装curl _ 统信UOS _ 麒麟KOS _ 中科方德

原文链接&#xff1a;源码编译安装curl | 统信UOS | 麒麟KOS | 中科方德 Hello&#xff0c;大家好啊&#xff01;今天我们来探讨一个非常实用的话题&#xff1a;在统信UOS、麒麟KOS以及中科方德桌面操作系统上如何从源码编译安装curl。Curl是一个广泛使用的命令行工具和库&…

【Kafka】Kafka高性能之道(六)

Kafka高性能之道 Kafka高性能原因 高效使用磁盘 1)顺序写磁盘&#xff0c;顺序写磁盘性能高于随机写内存。 2)Append Only 数据不更新&#xff0c;无记录级的数据删除(只会整个segment删s除)。读操作可直接在page cache内进行。如果进程重启&#xff0c;JVM内的cache会失效&a…

Pandas dataframe 中显示包含NaN值的单元格

大部分教程只讲如何打印含有NA的列或行。这个函数可以直接定位到单元格&#xff0c;当dataframe的行和列都很多的时候更加直观。 # Finding NaN locations for df.loc def locate_na(df):nan_indices set()nan_columns set()for col, vals in df_descriptors.items():for in…

grafana监控模板 regex截取ip地址

查看prometheus的node服务启动指标up&#xff0c;也可以查看其他的服务 配置监控模板 配置正则截取ip regex截取ip地址 /.*instance"([^"]*):9100*/ #提取&#xff08;instance"&#xff09;开头&#xff0c;&#xff08;:9001&#xff09;结束字段