kedao中间件-Java服务篇

一、概述

    本文主要介绍在kedao中间件中如何注册服务、编写服务代码、调用服务。
    使用 VSCode 作为开发工具,通过远程连接到开发服务器的方式,开展远程开发。

    kedao中间件官网:https://www.yckj-kedao.com
    系列文章:
        《kedao中间件-安装篇》
        《kedao中间件-C++服务篇》
        《kedao中间件-Vue开发篇》
        《kedao中间件-集群及发布篇》
        《kedao中间件-并发测试篇》
        《kedao中间件-Linux系统安装篇》
        《kedao中间件-数据库安装篇》

二、前提条件

    已经部署 kedao中间件 开发服务器、数据库,并且安装了 kedao creator 客户端,注册了用户。

    本文的涉及到开发用户、开发服务器和数据库服务器相关信息:
    1)开发服务器的IP:192.168.43.30,操作系统:Ubuntu24.04,系统用户:kedao
    2)kedao中间件的安装路径:/opt/kedao
    3)kedao中间件监听的端口:80,协议:http
    4)kedao中间件的注册用户:lym_test
    5)数据库服务器IP:192.168.43.135,端口:5432,用户:postgres,密码:postgres,数据库实例:asv_db

    如果还没有了解如何部署 kedao中间件 开发服务器,请参考《kedao中间件-安装篇》

三、创建Java系统

1、创建系统

    登录 kedao creator,在【基础功能】-【创建系统】功能中,点击右上角的创建系统按钮,打开创建系统对话框,填入系统名称为 prj_java_test,数据为 PostgreSQL,开发语言为Java,签名算法为 SHA256,如图:
在这里插入图片描述
    创建成功后,左侧菜单将自动出现刚才创建的系统,展开菜单,如图:
在这里插入图片描述

2、源代码目录结构

    Java项目源码的目录在: kedao中间件的安装路径/src_java,即 /opt/kedao/src_java
    进入 /opt/kedao/src_java 目录:

kedao@kedao:~$ cd /opt/kedao/src_java
kedao@kedao:/opt/kedao/src_java$ ls
lym_test

    目录说明:
    2)lym_test:kedao中间件的注册用户名,所有Java系统,都在该目录下

    进入 lym_test 目录:

kedao@kedao:/opt/kedao/src_java$ cd lym_test
kedao@kedao:/opt/kedao/src_java/lym_test$ ls
prj_java_test

    这时,看到刚才生成的Java工程prj_java_test,如果创建了多套Java工程,这里将会以工程名称生成相应的工程目录。
    继续进入prj_java_test工程目录:

kedao@kedao:/opt/kedao/src_java/lym_test$ cd prj_java_test
kedao@kedao:/opt/kedao/src_java/lym_test/prj_java_test$ ls
lib  pom.xml  src  target

    目录及文件说明:
    1)lib:第三方库文件目录,通常为空。第三方库通过Maven管理。
    2)pom.xml:Maven的配置文件。
    3)src:源代码目录。
    4)target:编译打包后生成文件的目录,每次通过Maven打包后会自动将*.jar包放拷贝到运行目录下。

    这里,需要重点了解 src 的结构,它的结构为:src/main/java/kedao用户/系统名称/,即:src/main/java/lym_test/prj_java_test
    进入 src/main/java/lym_test/prj_java_test

kedao@kedao:/opt/kedao/src_java/lym_test/prj_java_test$ cd src/main/java/lym_test/prj_java_test
kedao@kedao:/opt/kedao/src_java/lym_test/prj_java_test/src/main/java/lym_test/prj_java_test$ ls
Main.java  model  services  utils

    系统 prj_java_test 的目录说明:
    1)Main.java:工程默认入口 main() 方法的源代码文件。这里主要看下 package ,它的结构为 kedao用户.系统名称,即 lym_test.prj_java_test,如:

package lym_test.prj_java_test;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
    }
}

    2)model:数据结构类文件夹;
    3)services:服务文件夹;
    这里,需要重点了解 services 文件夹,进入到 services 目录

kedao@kedao:/opt/kedao/src_java/lym_test/prj_java_test/src/main/java/lym_test/prj_java_test$ cd services/
kedao@kedao:/opt/kedao/src_java/lym_test/prj_java_test/src/main/java/lym_test/prj_java_test/services$ ls
basic_func_employee  basic_func_funcRounter  basic_func_organization  basic_func_post  basic_func_role_permission  sys_login

    在services 是一个个模块文件夹,主要实现了组织机构、员工/用户、岗位、权限、菜单/路由配置、登录等基础功能。
    进入一个模块目录,以sys_login为例来了解一个模块的组成,进入sys_login目录:

kedao@kedao:/opt/kedao/src_java/lym_test/prj_java_test/src/main/java/lym_test/prj_java_test/services$ cd sys_login/
kedao@kedao:/opt/kedao/src_java/lym_test/prj_java_test/src/main/java/lym_test/prj_java_test/services/sys_login$ ls
svc_get_userInfo.java  svc_login.java

    sys_login包含了2个 *.java 文件,即服务源代码文件,每一个服务对应一个同名的 *.java 文件。
    4)utils:工具类文件夹,这里要关注 JDBCHelper.javaCheckUserLogin.java ,两个类文件,一个是数据库帮助类,一个是服务中的身份验证类,具体代码不在这里展开说明,自行阅读。
    到这里,对Java工程源代码的结构有了初步了解。

3、编译工程

    点击操作下的编译按钮,进行一次全编译,第一次编译需要下载依赖的第三方 jar 包,时间比较长,,如图:
在这里插入图片描述
    编译完成后,在 /opt/kedao/bin/lib/lym_test/prj_java_test 目录下看到编译好的动态库文件。

kedao@kedao:/opt/kedao/bin/lib/lym_test/prj_java_test$ ls
backup  db_connect.ini  db_sql  prj_java_test-1.0.jar  prj_java_test-1.0-jar-with-dependencies.jar

    也可以在 VSCode 中通过 Maven 进行编译打包,如图:
在这里插入图片描述

4、执行文件目录结构

    编译后生成的jar包存放路径为:kedao中间件的安装路径/bin/lib/kedao中间件的注册用户/工程名称/,即:/opt/kedao/bin/lib/lym_test/prj_java_test/
    进入**/opt/kedao/bin/lib/lym_test/prj_java_test/**目录:

kedao@kedao:~$ cd /opt/kedao/bin/lib/lym_test/prj_java_test/
kedao@kedao:/opt/kedao/bin/lib/lym_test/prj_java_test$ ls
backup  db_connect.ini  db_sql  prj_java_test-1.0.jar  prj_java_test-1.0-jar-with-dependencies.jar

    目录说明:
    1)backup:备份目录,目前没有使用。
    2)db_sql:数据库脚本目录,包含了数据初始化 和 查询表结构的SQL语句。注意:在【数据模型】功能中表结构导入数据库)用到了这里的SQL语句。
    3)db_connect.ini:数据库连接配置文件,根据 odbc.ini 对应的配置来设置。
    4).jar:jar包文件,这里分为2个文件,一个服务工程的jar文件,一个是第三方依赖包的jar文件。

5、数据库配置

    1)配置数据 /ect/odbc.ini

kedao@kedao:/opt/kedao/bin/lib/lym_test/prj_java_test$ sudo vi /etc/odbc.ini

    根据预先建好的数据库配置,数据库服务器IP:192.168.43.135,端口:5432,用户:postgres,密码:postgres,数据库实例:asv_db。配置如下:

[myPgDB]
Description = link to pg
Driver = PostgreSQL ANSI
Database = asv_db
Servername = 192.168.43.135
UserName = postgres
Password = postgres
Port = 5432
ReadOnly = 0
ConnSettings = set client_encoding to UTF8

    验证配置,执行命令 isql -v myPgDB

kedao@kedao:/opt/kedao/bin/lib/lym_test/prj_java_test$ isql -v myPgDB
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| echo [string]                         |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> 

    连接成功,quit 退出。
    2)配置 db_connect.ini

kedao@kedao:/opt/kedao/bin/lib/lym_test/prj_java_test$ sudo vi db_connect.ini

    文件内容设置如下:

[lym_test]
prj_java_test=postgres/postgres@myPgDB

    说明:

  • lym_testkedao中间件的注册用户
  • prj_java_test系统名称
  • postgres分别为数据库的用户密码
  • myPgDB/ect/odbc.ini 中数据库连接的节点名称
        3)java工程中配置数据库连接:
        在源代码的资源文件目录下 /opt/kedao/src_java/lym_test/prj_java_test/src/main/resources,编辑资源文件 prj_java_test.properties
        根据预先建好的数据库配置,数据库服务器IP:192.168.43.135,端口:5432,用户:postgres,密码:postgres,数据库实例:asv_db。配置如下:
# 数据库连接配置,此为 PostGreSQL 数据库的设置例子
database.driver=org.postgresql.Driver
database.url=jdbc:postgresql://192.168.43.135:5432/asv_db?stringtype=unspecified
database.user=postgres
database.password=postgres

6、数据库初始化

    如果已经初始化过,则跳过。初始化步骤:
    1)使用数据库管理工具连接到数据库,并打开预先创建好的数据库实例 asv_db
    2)在 db_sql 目录找到 PostgreSQL 数据库的初始化脚本:initialize_table_struct_for_PostgreSQL.sql
    3)在 asv_db 实例中执行初始化的脚本:initialize_table_struct_for_PostgreSQL.sql
    初始化完成后,数据库初始创建了:sys_employee、sys_function、sys_organization、sys_post、sys_role、sys_role_function_relation、sys_user、sys_user_role 等8张数据表,满足了一套系统最基本的框架结构需求,包括:组织管理、员工、角色、岗位、权限、登录、路由(菜单)配置等基础功能。
    这已经满足绝大多数的系统需求,可以直接使用,只需设计自己的业务数据表,添加业务即可;
    当然,如果不能满足自己系统的需求,也可以自行修改。

四、注册服务

    在kedao creator的菜单中找到【我的系统】-【prj_java_test】功能,如图:
在这里插入图片描述
    这里提供了系统基础功能的服务,只需根据业务需求注册新的服务。

1、增加模块

    点击增加模块按钮,在弹出的对话框中增加一个测试模块 mdl_test,如:
在这里插入图片描述

2、增加服务

    在模块列表中选中mdl_test,点击增加服务按钮,在弹出的对话框中增加一个测试服务 svc_test,如:
在这里插入图片描述

3、选择服务参数

    参数说明:
    1)默认的服务入参和出参分别是:SVC_REQUEST_OBJ<string> 和 SVC_RESPONSE_OBJ<string>
    2)SVC_REQUEST_OBJ 是默认的服务入参数据结构,Json 结构如下:

{
    "sys_head": {
		"usr_id": "",
		"org_id": "",
		"sys_id": "",
		"mdl_func_id": "",
		"login_key": ""
	},
	"data": ""
}

    其中data是一个泛型对象,也就是真正的请求业务数据;而 sys_head 主要保存服务请求者的身份信息,用于身份认证。
    Java中对应的数据结构:

public class SYS_HEAD  {
    public String usr_id = "";			// 用户登录名称
    public String org_id = "";			// 组织代码
    public String sys_id = "";			// 系统代码
    public String mdl_func_id = "";		// 功能代码
    public String login_key = "";		// 登录验证信息,每次登录成功后更新该值。服务调用时,必须传该值
}

public class SVC_REQUEST_OBJ <T> {
    public SYS_HEAD sys_head;			// 头包对象
    public T data;			            // 请求数据
}

    3)SVC_RESPONSE_OBJ 是默认的服务出参数据结构,Json 结构如下:

{
	"code": 0,
	"err_msg": "",
	"otl_exc": {
		"code": 0,
		"msg": "",
		"stm_text": "",
		"sqlstate": "",
		"var_info": ""
	},
	"data": ""
}

    其中data是一个泛型对象,也就是真正的返回业务数据;code 是返回码;err_msg 是错误信息;otl_exc 是数据库错误信息。
    Java中对应的数据结构:

public class OTL_EXC  {
    public int code = 0;			// 错误码
    public String msg = "";			// 错误消息
    public String stm_text = "";	// 导致错误的SQL语句
    public String sqlstate = "";	// SQLSTATE消息
    public String var_info = "";	// 导致错误的变量
}

public class SVC_RESPONSE_OBJ <T> {
    public int code = 0;			// 返回码
    public String err_msg = "";	    // 错误信息
    public OTL_EXC otl_exc;			// 错误信息
    public T data;			        // 响应数据
}

    根据业务需求选择自己的参数,这里,我们注册一个查询系统功能的服务,涉及到数据表是 sys_function,服务的入参是一个对象,返回是一个列表,入参选择界面,如:
在这里插入图片描述
    出参选择界面,如:
在这里插入图片描述
    注:选择参数的数据结构,在【数据模型】功能中维护。【数据模型】支持直接从数据库导入表结构功能,只需在数据库中设计好数据表,通过表结构导入功能一键导入,能节省很大部分的时间

4、保存服务

    选择完参数的最终服务注册界面,如:
在这里插入图片描述

    点击保存按钮,完成注册,返回服务列表界面:
在这里插入图片描述
    现在到系统源代码目录下,直接进入到服务所在目录:

kedao@kedao:/$ cd /opt/kedao/src_java/lym_test/prj_java_test/src/main/java/lym_test/prj_java_test/services/mdl_test
kedao@kedao:/opt/kedao/src_java/lym_test/prj_java_test/src/main/java/lym_test/prj_java_test/services/mdl_test$ ls
svc_test.java

    服务源代码文件 svc_test.java 已经生成。

五、编写代码

1、使用 VSCode 开发

    使用 VSCode 远程连接到开发服务器 192.168.43.30,连接用户为:kedao,选择根目录为 /opt/kedao,连接成功后,打开服务源码文件 svc_test.java,如图:
在这里插入图片描述
    下面是服务函数代码,代码结构比较简单,自己花点时间阅读理解。现在直接在服务函数中增加业务逻辑代码,,为了便演示调用服务,先把调用服务者的身份认证注释掉,整个服务代码如下:

package lym_test.prj_java_test.services.mdl_test;

import java.lang.reflect.Type;
import java.util.*;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import lym_test.prj_java_test.model.*;
import lym_test.prj_java_test.utils.*;
import kedaoUtils.SyncLog;
public class svc_test {
    SyncLog syncLog = new SyncLog();
    public void init_log(int msg_type) { syncLog.setType(msg_type); }

    public String exec_svc(final String in_data, final String http_headers) {
        Gson gson = new Gson();
        SVC_REQUEST_OBJ<SYS_FUNCTION> req = new SVC_REQUEST_OBJ<SYS_FUNCTION>();
        SVC_RESPONSE_OBJ<List<SYS_FUNCTION>> resp = new SVC_RESPONSE_OBJ<List<SYS_FUNCTION>>();
        int iRst = 0;
        StringBuilder sql_txt = new StringBuilder();
        ArrayList<String> lst_params = new ArrayList<>();
        OTL_EXC sqlMsg = new OTL_EXC();
        // 建立数据库连接
        JDBCHelper dbConn = new JDBCHelper();

        try {
            // 获取请求头包信息
            // HttpHeaders httpHeaders = gson.fromJson(http_headers, HttpHeaders.class);
            // 建立数据库连接
            dbConn.getConnection(sqlMsg);

            // 解析入参: 入参 in_data 字符串转对象 req
            Type type = new TypeToken<SVC_REQUEST_OBJ<SYS_FUNCTION>>(){}.getType();
            req = gson.fromJson(in_data, type);
            if (req == null) {
                resp.err_msg = "服务 svc_test :解包失败。";
                resp.code = -1;
                // 打印错误日志
                syncLog.cerr(resp.err_msg);
                // 断开数据库连接
                dbConn.close();
                return gson.toJson(resp);
            }

            // 检查用户登录有效性
            /*if (!CheckUserLogin.check_user_login(dbConn, req.sys_head.usr_id, req.sys_head.login_key)) {
                iRst = -1;
                resp.code = iRst;
                resp.err_msg = "服务[svc_test]验证身份信息失败。";
                syncLog.cerr(resp.err_msg);
                dbConn.close();
                return gson.toJson(resp);
            }*/

            // 开始事务
            dbConn.begin(sqlMsg);

        	// ---------------------------------------------------------------------
            // 编写业务逻辑代码
            // ---------------------------------------------------------------------

            // 清空参数
            lst_params.clear();
            // 组织SQL语句
            sql_txt.setLength(0);
            sql_txt.append("SELECT * FROM sys_function ");
            sql_txt.append("WHERE 1 = 1 ");
            if (!req.data.func_code.equals(""))
            {
                sql_txt.append("    AND func_code = ? ");
                // 参数
                lst_params.add(req.data.func_code);
            }
            if (!req.data.menu_title.equals(""))
            {
                sql_txt.append("    AND menu_title = ? ");
                // 参数
                lst_params.add(req.data.menu_title);
            }
            // 声明变量,接收查询结果
            ArrayList<SYS_FUNCTION> v_sys_functions = new ArrayList<>();
            // 执行查询
            dbConn.executeQueryToObjs(sql_txt, lst_params, v_sys_functions, SYS_FUNCTION.class, sqlMsg);
            if (sqlMsg.code != 0)
            {
                resp.code = sqlMsg.code;
                resp.err_msg = "服务[svc_test]-查询 sys_function 时发生错误";
                // 打印错误日志
                syncLog.cerr(resp.err_msg);
                // 事务回滚
                dbConn.rollback(sqlMsg);
                // 断开数据库连接
                dbConn.close();
                // 返回结果
                return gson.toJson(resp);
            }

            // ---------------------------------------------------------------------
            // 将结果赋值给返回对象
            // ---------------------------------------------------------------------
            resp.data = v_sys_functions;

            // 提交事务
            dbConn.commit(sqlMsg);
            // ------------------------------------------------------------------------------------------
            // 返回结果
            // ------------------------------------------------------------------------------------------
            resp.code = iRst;
            // 断开数据库连接
            dbConn.close();
            return gson.toJson(resp);
        }
        catch(Exception e) {
            // 回滚事务
            dbConn.rollback(sqlMsg);
            // 错误码
            iRst = -1;
            resp.code = iRst;
            resp.err_msg = e.getMessage();
            String out_str = gson.toJson(resp);
            // 打印错误日志
            syncLog.cerr(resp.err_msg);
            // 断开数据库连接
            dbConn.close();
            return out_str;
        }
    }
}

    服务开发说明
    每一个服务对应一个同名的类文件,每个服务中都有一个 exec_svc() 方法,服务的业务逻辑在该方法中实现:
    在utils工具类中封装了JDBCHelper.java帮助类,数据库操作通过它来实现 ,JDBC使用 hikari 连接池,需要在 JDBCHelper.java 中设置连接池参数,比如最小、最大连接数:

            config = new HikariConfig();
            config.setJdbcUrl(url);  // 修改为你的数据库URL
            config.setUsername(usr); // 修改为你的数据库用户名
            config.setPassword(pw);  // 修改为你的数据库密码
            config.setDriverClassName(driver);
            config.setPoolName("prj_java_test");
            // 连接池中允许的最小连接数,默认为10
            config.setMinimumIdle(10);
            // 连接池中允许的最大连接数,根据服务器性能设置
            config.setMaximumPoolSize(32);
            config.addDataSourceProperty("cachePrepStmts", "true");
            // 驱动为 每个连接缓存预准备的语句数,默认25。建议250-500
            config.addDataSourceProperty("prepStmtCacheSize", "500");
            // 驱动缓存SQL语句的最大长度,默认256。建议设置值大于执行的SQL语句的长度
            config.addDataSourceProperty("prepStmtCacheSqlLimit", "20480");
            // 提升数据库预处理语句的性能
            config.addDataSourceProperty("useServerPrepStmts", "true");

    JDBCHelper 中常用的函数有:
     1)原子服务,实现数据表的增删改查;使用原子服务时,数据表必须有唯一健字段
        atom_exec_delete()
        atom_exec_insert()
        atom_exec_select()
        atom_exec_update()
     2)执行SQL语句,无结果返回
        execute()
        executeUpdate()
        executeBatch()
     3)执行SQL语句,返回单个值(字符串)
        executeQueryToStringValue()
        executeQueryToIntegerValue()
        executeQueryToDoubleValue()
     4)执行SQL语句,返回多条记录容器 ArrayList<>
        executeQueryToObjs()
     5)执行SQL语句,返回单条记录的数据对象
        executeQueryToObj()
     6)执行SQL语句,返回多条记录 ArrayList<Map<string, string>>
        executeQueryToMaps()
     7)执行SQL语句,返回单条记录的 Map<string, string>
        executeQueryToMap()

    关于日志输出
    日志输出有3种方式,都支持多线程高并发:
     1)日志输出到 stdout,通常用在开发过程中打印日志,用来辅助测试,发布生产环境时,应该删除此类日志的输出
        syncLog.cout(“错误日志输出”);
     2)错误日志输出到 stderr 文件,通常用在服务发生错误时的日志打印
        syncLog.cerr(“日志输出”);
     3)日志输出到 log 日志文件,每天产生一个log日志文件,在 bin/log 目录下;kedao中间件默认输出每一个服务的执行情况
        syncLog.log(“日志输出”);

    注:整个服务编码过程是比较简单的,只需要关心业务逻辑的实现,对于数据库操作来说,就是组织编写业务逻辑的 SQL 语句 和 组织返回数据的过程。
    数据库开发帮助类 JDBCHelper,建议重点掌握。
    服务以模块分组,一个模块为一个文件夹。

六、编译/打包服务

    在 VSCode 中操作,如图:
在这里插入图片描述
    编译打包完成后,jar包自动生成到 /opt/kedao/bin/lib/lym_test/prj_java_test/ 目录。

七、调用服务

示例一

    在 kedao creator【注册服务】功能界面的操作列中,点击【测试】按钮,弹出测试服务界面,增加测试用例,然后点保存并测试,如:
在这里插入图片描述

示例二

    在 Postman 中调用,由于服务默认需求进行签名,才能调用,手动签名比较麻烦,先将服务设置为无签名模式。
    在 kedao creator【注册服务】功能界面的操作列中,点击【修改】按钮,将签名算法改为:
在这里插入图片描述

    由于svc_test 服务已经加载为需要签名验证模式,需要重启服务 sudo systemctl restart kedao 才会加载成不需要签名模式。

kedao@kedao:/opt$ sudo systemctl restart kedao

    从示例一的测试服务界面中赋值 url 和 请求参数 到Postman 中(或者点服务操作列中的修改,在弹出编辑界面中复制请求参数)。这里需要注意2点,一是 url 后面的 /api,不要忘记了;二是请求参数中的服务名称 svc_name 要把测试标识 @test去掉
    http方法:POST
    Url:http://192.168.43.30/api
    请求参数:

{
	"appid": "f4137243797841788feffdb4e4d1d15e",
	"sys_name": "prj_java_test",
	"mdl_name": "mdl_test",
	"svc_name": "svc_test",
	"body": {
		"sys_head": {
			"usr_id": "",
			"org_id": "",
			"sys_id": "",
			"mdl_func_id": "",
			"login_key": ""
		},
		"data": {
			"func_id": "",
			"func_parent_id": "",
			"func_code": "",
			"menu_title": "",
			"router_path": "",
			"component_path": "",
			"icon": "",
			"func_type": 0,
			"sort_num": 0
		}
	}
}

    Postman调用如图:
在这里插入图片描述

八、并发测试

    测试服务器配置:
    Windows操作系统:Windows10;CPU:酷睿9;硬盘:SSD PCIe 4.0 x4
    Linux操作系统:虚拟机 Ubuntu24.04-live-server
    CPU:2核心
    内存:4G
    kedao并发数:server_concurrency_process=16
    在 kedao creator【注册服务】功能界面的操作列中,点击【测试】按钮,打开测试界面,调用服务仍然是 svc_test ,但服务代码中去掉了业务逻辑,同时去掉数据库连接(避免数据库对测试的影响),只保留基本的入参和出参,并且加上签名算法,这次测试服务次数 10万次并发 1000(模拟客户端数量),测试结果如下图:
在这里插入图片描述

    同时,在 /opt/kedao/bin/log 目录下查看服务调用日志,服务在服务器端的执行时长在毫秒级别,QPS ≈ 900
    注:这里通过客户端模拟并发访问服务器上的服务,受到客户端与服务器之间的连接数和请求参数、响应参数网络传输时间的影响,实际服务器端处理服务能力的QPS比现在看到的值要高得多。

    关于server_concurrency_process的一点说明:
    1)server_concurrency_process的值要根据CPU核心数、服务的业务类型来设置;
    2)假如服务的逻辑都在本服务器上运算,那么server_concurrency_process的值要与CPU核心(超线程)数量相当;
    3)假如服务的部分逻辑在其他服务器上,比如访问数据库,执行SQL的运算在数据库服务器上,在执行SQL语句期间,服务处于等待状态(CPU处于闲置,可以让给其他服务运算),那么server_concurrency_process的值要与大于CPU核心(超线程)数量;至于大多少,就要一点一点的测试调整。可以按CPU核心(超线程)数量的倍数调整。
    4)如果服务器运算量很少,主要用于服务分发(比如集群主服务器),那就要设置的比较大了。

    注:这里并非服务器并发性能测试,而是测试某个服务中并发能力,同时检测服务的平均执行时间,以验证单个服务的性能,为服务代码性能调优提供参考依据。
    具体的服务器性能测试,参见《kedao中间件-并发测试篇》

    至此,Java服务篇完成。
    如何在代码中调用服务,将在Vue工程篇讲解。

九、总结

    kedao中间件提供了一套完整体系的Java系统结构,包括服务源代码、数据库结构和前端vue工程源码,只需添加业务数据表、设计服务、开发功能即可。
    初学者可以通过本系统深入学习,快速入门,缩短编程学习周期,快速晋升高手行列。
    久经沙场的老将也如虎添翼,利刃在手,所向披靡。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值