记一次基于Neo4j的网站开发经历

N 人看过

项目使用的技术栈

名称 作用端 开发文档
Neo4j 知识图谱处理数据库 参考介绍
Vue-Element-Admin 前端静态页面 中文文档
Flask Python后端接口设计 中文文档
Gunicorn WSGI HTTP服务器 参考介绍
Nginx 代理服务器 参考介绍

Neo4j

Neo4j依赖JAVA环境,所以在正式安装Neo4j之前应先确保本机正确配置的Java环境。

配置Java环境

# 1. 下载JDK:http://www.codebaoku.com/jdk/jdk-index.html
Example: jdk-15.0.2_linux-x64_bin.tar.gz
# 2. 解压
tar -xzvf jdk-8u131-linux-x64.tar.gz
# 3. 查看Java安装位置 >表示输出结果
which java
> /usr/local/jdk/jdk-15.0.2/bin/java
# 4.1 配置环境变量
vim /etc/profile
# 4.2 在文件末尾添加
export JAVA_HOME=/usr/local/jdk/jdk-15.0.2
export CLASSPATH=.:JAVA_HOME/lib:${CLASSPATH}
export PATH=$JAVA_HOME/bin:$PATH
# 4.3 退出保存
sudo source /etc/profile
# 4.4 验证
java -version
> java version "15.0.2" 2021-01-19
> Java(TM) SE Runtime Environment (build 15.0.2+7-27)
> Java HotSpot(TM) 64-Bit Server VM (build 15.0.2+7-27, mixed mode, sharing)

安装Neo4j

# 1. 下载Linux安装包
wget https://neo4j.com/business-subscription/?edition=enterprise&release=4.4.18&flavour=unix
# 2. 解压
tar -xzvf neo4j-community-4.4.18-unix.tar.gz
# 3. 启动
cd [Neo4j安装目录]/bin
./neo4j console
# 4. 浏览器中访问 http://localhost:7474
# 账号密码默认都是neo4j

项目中额外的配置

项目采用py2neo访问和操作Neo4j,基于Apoc插件对数据进行导入与导出操作

安装Apoc插件

GitHub上下载对应版本的jar包,并将jar放置在Neo4j安装目录里的plugins文件夹下。

本项目使用的是apoc-4.4.0.14-all.jar
可以在Neo4j的web端使用return apoc.version()查看是否安装成功

修改Neo4j的配置文件

# 文件路径:[Neo4j安装根目录]/bin/conf/config.ini
dbms.default_listen_address=0.0.0.0

dbms.security.procedures.unrestricted=algo.*
dbms.security.procedures.unrestricted=apoc.*
apoc.export.file.enabled=true
apoc.import.file.enabled=true

Vue-Element-Admin

一个基于vue和element-ui实现的后台前端框架。

安装与使用

环境要求

安装Node.js,为避免构建项目是发生奇奇怪怪的错误,建议手动安装最新版本

# 官网下载:https://nodejs.org/zh-cn/download/
Exmaple: node-v18.14.2-linux-x64.tar.xz
# 解压
tar -xvf node-v16.13.0-linux-x64.tar.xz
# 建立软连接,变为全局
ln -s [安装目录]/bin/npm /usr/local/bin
ln -s [安装目录]/bin/node /usr/local/bin
# 检验是否为全局
node -v
> v18.14.2

下载模板

Github下载模板

构建项目

# 开发阶段
npm run dev
# 发布阶段
npm run build:prod
# 清理缓存
npm cache verify

如果这里无法完成构建,一般需要卸载并重装最新版nodejs,删除项目中的node_modules、package-lock.json

主要项目目录

  • mock:可用来生成服务端的模拟数据
  • src/views:视图文件夹
  • src/router/index.js:配置页面路由

Flask和Gunicorn

直接pip安装即可

启动一个最简单的Flask服务

# 入口文件app.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ =='__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)
# 运行文件之后可以在http://127.0.0.1:5000访问

本项目布局

/flask-app
├── App
│   ├── __init__.py
│   ├── settings.py                 # Flask配置文件
│   ├── api/
│   │   └── api_test.py             # 自定义API文件:定义blueprint和route
│   └── models
│       ├── __init__.py
│       └── sub_model/
│               ├── __init__.py
│               └── model1.py       # 自定义接口所需函数
├── statics                         # 存放静态数据资源
│   ├── data1/
│   ├── data2/
│   └── data3/
└── app.py                          # 项目入口文件

Gunicorn

为什么需要Gunicorn或uWSGI?

由于Flask自带的wsgi性能低,仅适用于调试开发阶段,在真实线上必须用Gunicorn+Nginx获得更好的性能和安全性,其本质是为了提升服务器并发处理能力。

为什么有了Gunicorn还需要再套一层Nginx?

Nginx更安全Nginx能更好地处理静态资源(通过一些http request header),Nginx也可以缓存一些动态内容;Nginx可以更好地配合CDN,可以进行多台机器的负载均衡;不需要在wsgi server那边处理keep alive,让Nginx来处理slow client;还有一个更隐蔽的区别是,像uWSGI支持的是wsgi协议,Nginx支持的是http协议,它们之间是有区别的。
一台服务器同时运行多服务或者前后端分离时,可以用Nginx来分发。

使用Gunicorn启动Flask应用

# 1.启动
gunicorn -w 4 -t 300 -b 0.0.0.0:5000 app:app
# 2.查看状态
# 使用树形结构查看PID
pstree -ap|grep gunicorn
# 根据端口查看PID
lsof -i:5000
# 3.重启
kill -HUP [master_PID]
# 4.关闭
kill -9 [master_PID]

Nginx

安装

# 安装
sudo apt update  # 更新安装源
sudo apt install nginx
# 验证
sudo systemctl status nginx
# 启动 停止 重启
sudo systemctl start/stop/restart nginx
# 测试启动
http://localhost

配置

配置文件说明

  • /etc/nginx/nginx.conf:主配置文件
  • /etc/nginx/conf.d/*.conf:独立配置Server,通过引用的方式调用
  • /etc/nginx/sites-enabled/*.*:Nginx会加载该目录下任何名称的配置文件
  • /etc/nginx/sites-available/*.*:用于存放网站的配置文件,意为可用的网站列表,用于在需要时链接到sites-enabled中作为需要启用的网站。

本项目的配置

部署前端

# 发布Vue
npm run build:prod
# 将生成dist目录:其中静态文件为[static、favicon.ico、index.html]
# 可以选择移动或是复制到一个单独的路径,也可以直接使用dist路径
# 在本项目中我是选择了前者
mv dist [项目路径]/web

部署后端
使用Gunicorn启动Flask

修改Nginx服务配置

# /etc/nginx/conf.d/myApp.com.conf
server {
    listen 80;  # 监听端口
    server_name XXXXXXXX.imdo.co;  # 花生壳内网穿透域名
    charset utf-8;
    client_max_body_size 75M;
    # 前端-Vue-Element-Admin
    location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    root  [项目路径]/web;  # 站点的根目录
    try_files $uri $uri/ /index.html;
    index  /index.html;
    }
    # 后端-Flask+Gunicorn
    location /api/ {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    add_header Access-Control-Allow-Methods *;
        add_header Access-Control-Allow-Origin $http_origin;
        proxy_pass http://127.0.0.1:5000/;
        # 设置超时,默认30s,避免后台响应时间长触发504错误
        proxy_connect_timeout 300s;
        proxy_send_timeout 300s;
        proxy_read_timeout 300s;
    }
}

Gzip配置
由于vue打包之后的chunk-libs.js文件过大导致前端页面加载过慢,一种简单的处理方式是Nginx服务器配置静态压缩

server{
    # 将下面的内容直接合并到/etc/nginx/conf.d/myApp.com.conf的server{}中
    gzip on;
    gzip_static on;
    gzip_min_length 1k;
    gzip_comp_level 9;
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
    gzip_vary on;
    gzip_disable "MSIE [1-6]\.";
}

本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 (CC BY-NC-ND 4.0) 进行许可。