GWA2 PHP Memcached自动追加服务器连接?一例缓存服务被击穿的异常分析。

GWA2 PHP Memcached自动追加服务器连接? 一例缓存服务被击穿的异常分析。

最近在一次网络应用服务器巡检时,发现负载特别高,与当时的流量不成比例,于是就进一步地核查看看为何负载高。

首先发现负载高是由于数据库(-MySQL)的查询读取查询异常的多,并发连接有上百个,多数是简单的查询,可见不是数据库结构问题,而是自然流量触发的数据请求。

缓存被击穿了吗?为何这些显而易见的查询会出现那么多并发?稍微留意发现,有些查询SQL是相同的,于是可以大致推断,缓存层出问题。确认缓存被击穿,对一个线上应用来说是一件很恐怖的事情。

@memcached
进一步的诊断缓存服务(-Memcached),使用telnet 工具连接本地缓存服务,通过 stats命令查询,缓存服务正常,有正确的get/set数据,有get_hits/misses统计,缓存服务没有问题。

下一个疑点就是在代码层,PHP连接模块Memcached的地方有问题吗? 调用缓存服务的存取操作有异常吗?

打开 GWA2 PHP 的 inc/config.class 核对连接缓存服务,没有问题,基于IP地址和端口的连接配置;
打开 inc/webapp.class 显示读取缓存的成功与失败日志记录,发现有成功,有失败。
进一步地打开 inc/webapp.class 的 readObject/writeObject的日志记录;打开 inc/cachea.class, inc/memcached.class 中的 set方法的日志记录。

日志记录显示,有成功的,结果是预期的;当失败时,memcached发回的错误代码和错误消息是,35 / Server Marked Dead。

这听起来不可思议,当下的memcached服务,只有一个 127.0.0.1 基于IP的连接配置,怎么会有成功和失败的状况同时存在呢?

更进一步地输出当前 sever list发现,的确有两个缓存服务的配置:

memcached servers:a:2:{i:0;a:3:{s:4:”host”;s:9:”127.0.0.1″;s:4:”port”;i:11211;s:4:”type”;s:3:”TCP”;}i:1;a:3:{s:4:”host”;s:33:”/bin/memcached/memcached.sock”;s:4:”port”;i:11211;s:4:”type”;s:6:”SOCKET”;}}

明明在 inc/config.class 中只配置了 127.0.0.1 的一个缓存服务,而第二个 /bin/memcached/memcached.sock 从哪里来的呢?显然这个 .sock 的连接已经被标注了 DEAD 但并没有从 server list 里移除,这也让人费解,毕竟在 Memcached的连接初始化时声明了自动移除DEAD Server。

$this->mcache = new Memcached(self::persist_ConnId);
$this->mcache->setOption(Memcached::OPT_REMOVE_FAILED_SERVERS, true);
$this->mcache->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);

一种合理的解释大致是,/bin/memcached/memcached.sock 文件存在,然后Memcached 服务会自动探测,然后追加到当前的 server list里。会这样智能吗? 可能要分析PHP Memcached的扩展模块源码 和 Memcached的服务源码相应的模块才能确认。

导致存在 /bin/memcached/memcached.sock 文件并且使用 127.0.0.1 的原因是,第一次启动 Memcached服务时,指定了 -s /bin/memcached/memcached.sock 然后kill关闭,再次启动时不带 -s 而是指定了 IP/Port,这样 /bin/memcached/memcached.sock 就被遗留下来而没有用。

之所以不再使用 -s /bin/memcached/memcached.sock 模式,是由于该 Memcached服务需要在 PHP和 Java之间共享,而Java读取操作 .sock 文件相对复杂,暂时没有集成到 GWA2 Java中去。而 -s /bin/memcached/memcached.sock 与 IP/Port 在Memached服务看来又不能共存。

由于 /bin/memcached/memcached.sock 是上次启动后遗留下来的,所以其状态可能并不是 DEAD, 所以 OPT_REMOVE_FAILED_SERVERS 也未能生效?

针对这个问题,手工移除 /bin/memcached/memcached.sock , 然后重启 HTTPD ,  GWA2 PHP 再次正常运行,缓存服务不再报错,也没有缓存服务被击穿,导致数据库查询并发大,进而系统负载高的问题出现。


-GWA2 是”通用网络应用架构( General Web Application Architeture )”,基于 -GWA2 可以轻便构建各种网络应用程序,
包括复杂的在线购物商城、 旅游交易平台、社群或者社交网站和新闻资讯网站等,
也包括各种企事业单位网上门户,在线交互及服务作业系统等.
还可以包括为NativeApp做服务器端支持, 甚至是WebApp的全部.
-GWA2 是为数不多的支持跨开发语言的应用框架,目前支持 -Java, -PHP, -Perl, -Aspx and -Python .

-GWA2 is a “General Web Application Architecture” and based on -GWA2 developers can easily build a variety of network applications,
including complex online shopping malls, travel trading platforms, community or social networking sites and news information sites, etc.
Also the applications include various online portals of enterprises and institutions, online interaction and service operations systems.
Moreover it contains server-side support for NativeApp, or even all of the WebApp.
-GWA2 is one of the web frameworks which provide cross-language support for -Java, -PHP, -Perl, -Aspx and -Python at present.

-GWA2 is E.A.S.Y 
Easy Along, Swift Yield
轻松启动, 快速产出.

发表在 -GWA2, 编程技术, 计算机技术 | 标签为 , , | 一条评论

Google Books亮月亮科技Apache SoftwaresPdf Drive

㊗️ GWA2/吉娃兔八周年啦!GWA2内置模板引擎成功由Smarty替换为Hanjst

2011.01 — 2019.01 🎉

GWA2/吉娃兔 八周年啦!GWA2内置模板引擎成功由Smarty替换为Hanjst!
欢迎试用体验“轻松启动,高效产出 (EASY模式, Easy Along, Swift Yield)”的“通用网络应用开发框架”。

 314 commits / 8 years , 
3.27 commits / month.
几乎每周 GWA2 有更新,在成长.

GWA2/通用Web开发框架, 2011.01 — 2019.01 ,已经走完八个年头。这期间,GWA2 的设计思想始于Java开发语言,第一个完成的版本却是PHP开发语言的 GWA2PHP。

八年来,GWA2 从单一的PHP版本,后续又逐渐完成了 Java生产就绪版本和 Perl的生产就绪版本,规划中的 Aspx 和 Python版本预计在未来2-3年完成生产就绪的初始版本。

 八年来,GWA2成功部署无数大大小小的商业项目,并成功孕育出通用管理信息系统:-gMIS / -吉米斯

1. GWA2的价值回顾

GWA2的设计与研发思想是面向对象,面向物理世界的,在将这种思想进行工程化实现时,也经历过很多曲折。

我们团队努力要探索和实现的是一种前无古人的问题:

到底能不能实现软件研发框架的跨开发语言?

如果软件开发框架能够跨开发语言,该如何进行?需要遵循哪些规则?有无最佳实践(Best practice)?

计算机科学与技术仍然年轻,信息产业也只是经历短暂的几十年的发展,编程语言及软件工程领域,新思想,新观念,新技术,新尝试仍层出不穷、日新月异。我们庆幸在这波时代巨浪中以 GWA2 的研发探索参与其中,试图回答“软件研发框架是否能够实现跨语言”这样的问题。

从本质价值上说,之所以用软件开发框架,也是前人探索和总结的经验,“为解决一个开放性问题而设计的具有一定约束性的支撑结构”,能够“更迅速和方便地构建完整的解决问题的方案”。GWA2作为单一开发语言的开发框架,承载了这一使命,并严格遵循了面向对象,面向业务等开发规范,在扩展性、易用性方面取得可喜的进步。

在单一开发语言等软件框架的横向比较中,GWA2 也有出色的表现,如GWA2的PHP版本,“-gwa2 vs -thinkphp”, -R/L2SP 。

为何要有跨编程语言的开发框架?

我们预设一名软件工程师在其一生的职业生涯中,绝大多数人不会也不能只懂一门开发语言,在不同的职业阶段,在不同的应用项目上,甚至在不同的历史时期,会或多或少地使用两种以上的开发语言进行工作。如此以来,软件工程师就面临要学习两种以上的开发语言,然后每种开发语言再学习一种软件开发框架。

GWA2 的初衷就是解决掉后面这个问题,软件工程师在A语言掌握和习得的软件开发框架知识,可以无缝地在B语言上继续使用。无需再学习,也不必再学习另外一种额外的软件开发框架。此其核心价值之一。

其二,籍由跨开发语言的“上帝视角”,我们可以审慎地对待每一种开发语言,汲取该开发语言的优点而实现和部署在其他开发语言的相应GWA2的版本中,抛弃其缺点与不足;积极参与各个开发语言社区,以促进各个开发语言的竞向发展。从而实现在不断完善和增强改进GWA2的基础上,推动人类在软件领域的集体进步。

2. GWA2内置模版引擎由从Smarty 到Hanjst

GWA2最近较大幅度的改进是其内置模版引擎由原来的 Smarty 改为 Hanjst。

这首先得益于 Hanjst的生产环境就绪版本的发布(-Hanjst, -汉吉斯特, -R/U2SK )。谈及改动的动机,大致由如下几点。

1) Smarty 本身已经足够好,足够强大到满足生产环境需求,这是 Smarty 在之前我们的遴选中能够胜出的原因之一。Smarty 简洁明了的表达语言很接近自然语言,令其学习门槛低,容易上手,而进阶应用也保持了这种简洁,所以学习曲线并不陡峭。

我们在 GWA2PHP 中集成了 Smarty ,他工作地很好。当我们研发 GWA2Java时,发现 网上 Smarty爱好者已经有将 Smarty 移至成 Java 版本的, Smarty4J ,于是我们也顺理成章地集成了 Smarty4J。

遗憾的是, Smarty4J 是大约7-8年其版本,且其后没有更新,只兼容 Smarty 2的语法,这极大地限制 GWA2Java 进一步的发展。

2)寻求跨开发语言的 模版引擎的想法一直在我们的 Todo List上,最早在 2016年我们就尝试一种 Jstpl的模版引擎创制。

当初的想法一是对跨开发语言的模版引擎的认识,逐渐归集到 JavaScript身上,二是网上现存的JavaScript的模版引擎虽各有千秋,各具特色,但拿出来跟 Smarty相提并论但并没有,多数JavaScript模版引擎均属画地为牢自我限制,然后孤悬一偶。

同时,作为 Smarty的重度用户,在深度使用 Smarty时,也发现一些不足。

3)带着这些想法,我们希望创制一种能够在语法、功能上与Smarty媲美,基于JavaScript的能够跨开发语言的模版引擎。

令人惊奇的是,Smarty 爱好者如此广泛,让 Smarty JavaScript也被研制出来了: JSmart (-R/s2SR ) 。这个开源的模版引擎也在我们的考察范围之内,令人稍微不满意的是,我们无法接受下面这样的模版表达式:

<script id="test_tpl" type="text/x-jsmart-tmpl">
    Hello {$name}
  </script>

我们认为, 第一行和第三行应该去掉。参考: -R/U2SK 。

4)加上其他要改进的 Smarty的语法,我们最终还是决定新造一个我们认为可以做得更好的轮子, Hanjst / 汉吉斯特。

从2016年开始,历时3年的探索与研制,2019年元旦开花结果,-Hanjst, Han JavaScript Template Language/Engine 终于发布一个生产就绪版本,中文名 -汉吉斯特。详见:-R/U2SK 。

3. GWA2的下一个八年

2019.01 — 2027.01

我们会将 GWA2 持续研发下去,继续完善和增强,不断增加和扩张公用类库,拓展增加更多的开发语言版本,如 GWA2Python版本, GWA2Apsx版本等。

我们还将继续完善作为GWA2的集成部分,也可以独立发展的 Hanjst模版,以减少和降低研发人员在使用模版方面的困扰。

最主要的,GWA2 的各个版本都将被部署和应用到更多商业项目中,在其中被检视、检验,并发现问题、修正问题、改进性能等,这些实践是GWA2 不断进步的前提和基石。

我们相信,信息产业、软件行业在未来信息时代的人工智能普遍应用阶段更逐渐成功社会发展和人类进步的基础技术领域和基本设施范畴。

🎉期待GWA2 的下一个八年,祝愿我们共同的下一个八年更美好!㊗️

 


 

-GWA2 是”通用网络应用架构( General Web Application Architeture )”,基于 -GWA2 可以轻便构建各种网络应用程序,
包括复杂的在线购物商城、 旅游交易平台、社群或者社交网站和新闻资讯网站等,
也包括各种企事业单位网上门户,在线交互及服务作业系统等.
还可以包括为NativeApp做服务器端支持, 甚至是WebApp的全部.
-GWA2 是为数不多的支持跨开发语言的应用框架,目前支持 -Java, -PHP, -Perl, -Aspx and -Python .

-GWA2 is a “General Web Application Architecture” and based on -GWA2 developers can easily build a variety of network applications,
including complex online shopping malls, travel trading platforms, community or social networking sites and news information sites, etc.
Also the applications include various online portals of enterprises and institutions, online interaction and service operations systems.
Moreover it contains server-side support for NativeApp, or even all of the WebApp.
-GWA2 is one of the web frameworks which provide cross-language support for -Java, -PHP, -Perl, -Aspx and -Python at present.

-GWA2 is E.A.S.Y 
Easy Along, Swift Yield
轻松启动, 快速产出.

 

发表在 -GWA2, -Hanjst/-汉吉斯特, 服务器运维, 编程技术, 计算机技术 | 标签为 , , , | 3条评论

捐助乌克兰Help Ukraine老板选址BossXuanzhiUfqiFina有福金融UfqiWork有福工坊

Apache Tomcat JDBC连接池接入MySQL数据库的NamingContext异常排解

在最近新部署的 -GWA2 in Java 的实例中,一切进展顺利,唯独在启用连接池访问 Tomcat 接管的 MySQL 数据库连接池时报错出异常。问题排解过程曲折,值得记录如下。服务器端日志信息如下:

java.lang.ClassCastException: class org.apache.naming.NamingContext cannot be cast to class javax.sql.DataSource (org.apache.naming.NamingContext is in unnamed module of loader java.net.URLClassLoader @5383967b; javax.sql.DataSource is in module java.sql of loader ‘platform’)

根据报错信息,找出报出问题的代码段如下:

if(this.hasSocketPool){
try{
    this.ctx = new InitialContext();
    this.ds = (DataSource)ctx.lookup(“java:comp/env/jdbc/”+this.myDb); //- error!
}
catch(Exception ex){
ex.printStackTrace();
}
}

就是在 ctx.lookup 返回对象进行强制类型(DataSource)转换时发送错误,抛出异常。

让人费解的是,这些代码在另外的运行时环境时,运行良好,难道跟新部署的环境有关? Tomcat 9.0+ / MySql 8.0+ / Java 11.0+ ?

报错信息的字面意思是 “A类不能强制转为B类(A类在未命名的加载器模块C中,B类在platform加载器的java.sql模块中)”。根据这些理解,大致是加载的类出现错乱了,于是沿着这个思路搜索一下网上其他同学的过往经历。

网上的资讯大致可以分为两种,一种是的确加载错了 org.apache.naming.* 相关的类,另外一种更大的可能是没有正确地在 Tomcat中配置 conf/server.xml 和 conf/web.xml ,这个参照 Tomcat的手册可以很快排除。

而第一种,加载错乱的情况,在GWA2 Java中,理论上不应该发生,因为我们在 inc/MySql.class 中明确地声明了加载如下类:

<%@page import=”javax.sql.DataSource,
java.sql.DriverManager,
java.sql.ResultSet,
java.sql.PreparedStatement,
javax.naming.Context,
javax.naming.InitialContext”%>

显然,其中并没有显示地加载任何 org.apache.naming 相关的类。尽管如此,我们还是在代码层面将类的调用再一次的明确下来,使用类的绝对路径以避免可能引起的混淆。改进后的代码为:

javax.naming.Context ctx = new javax.naming.InitialContext();
javax.naming.Context envCtx = (javax.naming.Context)ctx.lookup(“java:comp/env”);
envCtx = (javax.naming.Context)envCtx;
Object dsObj = envCtx.lookup(“jdbc/”+this.myDb);

很遗憾,带上绝对路径的类的声明与应用于事无补。

迫不得已,我们决定将部署归零,清空所有配置,重新下载最新版的 Tomcat, GWA2 Java等,然后重新安装,再次运行时,很遗憾,问题依旧!

几乎要放弃了,这种可能由于软件不匹配导致的问题,已经超出应用层和代码层的解决能力范畴。不能放弃,还有最后一招——分析源代码——还没使用。于是耐下心来,翻看 Tomcat 的API文档和 Java 的API 文档,逐个对象查询、分析,并在程序中逐个步骤进行断点测试。

javax.naming.NamingEnumeration dsList = envCtx.list(“jdbc/”);
debug(“dsObj:”+dsObj+” / “+dsObj.toString()+” ctx:”+ctx+” envctx:”+envCtx+” envctx.getEnv:”+envCtx.getEnvironment());
debug(“dsList:”+dsList+” mydb:”+this.myDb);
while(dsList.hasMore()){
    debug(“dsList: next:”+dsList.next());
}

-R/B2SR 
https://tomcat.apache.org/tomcat-9.0-doc/api/index.html

-R/72SS 
https://docs.oracle.com/en/java/javase/11/docs/api/java.naming/javax/naming/Context.html

进一步地日志输出中,我们看到了蛛丝马迹,在测试代码的第二步,原本应该返回 javax.naming.Context 对象的,却被 Tomcat 替换为 org.apache.naming.NamingContext. 所以后就几乎全都跑偏了。

Thu Jan 03 05:56:32 UTC 2019 dsObj:org.apache.naming.NamingContext@368631b7 / org.apache.naming.NamingContext@368631b7 ctx:javax.naming.InitialContext@4f52e2fc envctx:org.apache.naming.NamingContext@5b51d294 envctx.getEnv:{}
Thu Jan 03 05:56:32 UTC 2019 dsList:org.apache.naming.NamingContextEnumeration@152fa16f mydb:
Thu Jan 03 05:56:32 UTC 2019 dsList: next:userdb: org.apache.tomcat.dbcp.dbcp2.BasicDataSource
Thu Jan 03 05:56:32 UTC 2019 dsList: next:contentdb: org.apache.tomcat.dbcp.dbcp2.BasicDataSource
Thu Jan 03 05:56:32 UTC 2019 dsList: next:newsdb: org.apache.tomcat.dbcp.dbcp2.BasicDataSource

当我们调用 org.apache.naming.NamingContext 对象的方法 .getEnvironment 和 .list 进一步地输出时发现,配置信息 userdb, contentdb 和 newsdb 都在。 为何返回是一个包含列表的对象NamingContext 而不是一个 DataSource类型的数据?

谜底揭开!在当前运行时环境中关键变量 this.myDb 为空,当传入一个空值的 资源标识符(数据库资源)时,ctx.lookup 不是报错未找到,而是返回了DataSource的父类 NamingContext!

(DataSource)ctx.lookup(“java:comp/env/jdbc/”+this.myDb); //- error if empty myDb

修正方式:
1)在 GWA2 Java中对 this.myDb 做兼容,如果为空,则不启用默认数据库连接池的连接;
2)尝试递交 bug给 Apache Tomcat 开发组,修改报错信息或改进返回值类型,减少对用户可能产生误导的信息。
3) 尝试回复stackoverflow上类似悬而未决的一问题。

翻阅源代码,仔细查看API文档依然是解决问题的终极大杀器之一。

-GWA2 是”通用网络应用架构( General Web Application Architeture )”,基于 -GWA2 可以轻便构建各种网络应用程序,
包括复杂的在线购物商城、 旅游交易平台、社群或者社交网站和新闻资讯网站等,
也包括各种企事业单位网上门户,在线交互及服务作业系统等.
还可以包括为NativeApp做服务器端支持, 甚至是WebApp的全部.
-GWA2 是为数不多的支持跨开发语言的应用框架,目前支持 -Java, -PHP, -Perl, -Aspx and -Python .

-GWA2 is a “General Web Application Architecture” and based on -GWA2 developers can easily build a variety of network applications,
including complex online shopping malls, travel trading platforms, community or social networking sites and news information sites, etc.
Also the applications include various online portals of enterprises and institutions, online interaction and service operations systems.
Moreover it contains server-side support for NativeApp, or even all of the WebApp.
-GWA2 is one of the web frameworks which provide cross-language support for -Java, -PHP, -Perl, -Aspx and -Python at present.

-GWA2 is E.A.S.Y 
Easy Along, Swift Yield
轻松启动, 快速产出.

发表在 -GWA2, 编程技术, 计算机技术 | 标签为 , , , , | 留下评论

老板选址BossXuanzhiUfqiFina有福金融UfqiWork有福工坊UfqiNews有福常在

Hello 2019! Hanjst/汉吉斯特 模板语言及引擎创新发布

Hello 2019!  Hanjst/汉吉斯特 模板语言及引擎创新发布。

值此一元复始之际,恭祝 网友们新年万事如意!
寄望 Hanjst/汉吉斯特能帮助大家从各种模板中解脱出来,为人类做出更大的贡献。

1. 背景

网页模板语言/引擎缘起于 MVC 思想的引入。当软件项目膨胀复杂到足够大时,软件研发人员与UI/UE设计人员就需要分别独立出来,其中设计制作人员工作的V(View)部分需要用模板语言与引擎。

模板语言及引擎的设计与研发工作是一项既简单又复杂的工作。简单地说,模板就是一种变量替换的工作,在模板中预留相应的占位符和变量标记,模板引擎在工作时在相应的占位符将对应的变量替换为实际对应的数值即可。

复杂地说,模板语言是一种全新表达语言的设计,设计一门语言,其难度是可想而知的,这门语言要能够满足日常沟通之需要,首先或入门的是语言设计者要考虑的,是该模板语言能够普遍接受和广泛使用,这样语言才有生命力。无疑,简洁而表意丰富是重要而优先的考虑项。

先行者已经在模板领域创制出大量符合各种需求的模板语言与模板引擎,这里是一个简单的归集  -R/U2SJ ,  为了更好的梳理其发展类别,我们绘制了一个 Mind map:

Fig1. 网页模板语言分类概括

2. 问题讨论

如在Fig1中所展示的,模板语言及引擎有很多种类,每个分类下面又有不同的应用实例,可谓多姿多彩,琳琅满目。实际上,在网络上搜索一下可能会发现,网页模板语言和引擎多到不胜枚举,连JSP、PHP这样的开发语言都可以归类为某种模板语言的范围。

通过脑图的分析,我们发现在这一领域还有两个问题没有得到解决,或者没有得到很好的解决:1)服务器端,有没有一种模板语言与引擎可以实现跨开发语言的? 2)客户端/浏览器终端,有没有一种模板语言与引擎能够不需要Script tags的?

针对第一个问题,我们搜索了多次,发现的确有针对不同开发语言而设计的模板语言与引擎,多数只是针对某几种主流语言开发了模板编译引擎,只是做到“准跨开发语言”,另外就是,这些看似高级的模板语言与引擎,大多数都是私有软件,非开源,需要购买获取授权才能使用。

至于第二个问题,Script tags,一般的定义是这样的,如果我们在客户端使用JavaScript来写一个模板,通常都需要先声明一段区块头部,然后完事之后再声明一下区块尾部,这个区块的头尾部使用Script tags来实现的,如下:

<script id="template" type="x-tmpl-mustache">
Hello {{ name }}!
</script>

这是令人不悦的,为何要表述一句 “Hello {{name}}”, 无辜地多写了第一行和第三行,不能省掉吗?

令人无可忍受地还有其他的,
3)logicless 。如果一种模板语言无法表达逻辑,这是什么逻辑?
4){{name}}。为何必需用两个“{{” ,而不是一个“{”?
5)<#list>. 为何要用 “<#” , 能再简洁易懂些吗?


Fig2 腾讯理财通客户端等JavaScript模版

从 Fig2 中我们可以看到这些令人不满意等地方,函数等调用 | f2y | n2t 借用了命令行管道等意思,如果有参数呢?能否写成:

f2y(n2t(IMonthProfit)) 
or
IMonthProfit.n2t().f2y()

通过Fig2 我们还发现 模版语言,尤其是 JavaScript 模版语言在App上应用等依然存在,模版等使用并没有随着Web向App转换而减少。

于是,怀着这些不满意,我们设想满足以下需要来设计一套新的模板语言与引擎:

A)跨开发语言,与服务器开发语言不做绑定,同时开源,免费使用;
B)去掉 Scripts tags;
C)基于JavaScript提供,同时与服务器端一致强大而复杂的表达、表示能力。

如能满足以上,我们在继续研制 -GWA2  / -吉娃兔 的道路上,有望一通各个开发语言的模板引擎,而不是在开发 Java 版本的 GWA2时 选择 Velocity, 在 开发 PHP 版本的 GWA2 时选择 Smarty 等问题。

以语言学家的视角来设计这套模板语言与引擎,
以工程师的思维来实现语法、语义的程序化表达,
这就是 Hanjst 模板语言及引擎。

3. Hanjst, 汉吉斯特 模板语言及引擎

Hanjst是一种基于JavaScript的模板语言及解析引擎,她可以运行在客户端,也可以运行在服务器端。

Hanjst能够表述逻辑控制,能够实现与服务器端模块语言相同的功能。

特征/功能

  • Hanjst运行在客户端时完全客户端解析,节省服务器端计算资源;

  • Hanjst模板语言独立,不与服务器端开发语言做任何绑定;

  • 纯粹的MVC,层间数据用JSON格式传递;

  • 常见模板语言功能全支持,附带复杂而强大的JavaScript编程能力;

  • 无学习成本,直接使用JavaScript书写模板语言;

  • 开源的,免费使用;
  • ….

Han 是我妻子的姓(韩), 也是出现我女儿和儿子名字中的音节。Han 也是中文“汉族”的意思。

Hanjst 模板语言及引擎设计用来终止在HTML模板语言领域不断地“再造轮子”的活动,尽管这听起来有些怪异。

Hanjst 的语法与基于 PHP 的Smarty语言有相似的地方,原因是我们借鉴了 Smarty的一些设计,之所以如此,是我们赞同 Smarty 在语言精炼方面精益求精的探索( -R/x12SU  )。

Note that the PHP syntax uses 5 punctuation characters to display a simple variable: <?=?>, whereas Smarty uses 2: {}

Hanjst 依托JavaScript内部对象及函数的功能,赋予了在模板中直接调用这些功能的能力,实现了媲美服务端模板语言一致的表示、表达能力。如表达截短一个字符串:

{$myString.substring(0, 10)} 

 

4. 发展规划及设想

Hanjst 模板语言及引擎已发布在 -GitHub 上,地址为: https://github.com/wadelau/Hanjst

Hanjst 模板语言及引擎的样例展示地址, -Hanjst , -R/j2SP 。 现在就可以点开尝鲜。

Hanjst 模板语言及引擎的参考手册在编辑中,不日将在线发布。

Table of Contents

I. What is Hanjst?
1.
Hanjst Installation
2.
Basic Settings
II. Hanjst for Template Designers
3.
Syntax and Semantic
4.
Variables
5.
Modifiers on Variables
6.
Built-in Functions
7.
Warnings and Errors
III. Hanjst Template for Programmers
8.
JSON Data
9.
Includes
10.
Compile and Cache
IV. Search Engine Optimization
11.
HTML Head Element
12.
Plain Content Div Element
13.
Robot-oriented Links
V. Advanced Applications for Hanjst
14.
Embedded in HTML Elements

 

5. 不足及改进

目前已知的不足之一是在客户端运行编译模板文件时,对搜索引擎不够友好。

针对这一问题,我们提供了优化HTML head, 曝露 Hanjstjsondata 等方式进行补充。

其他的,请大家试用并反馈。

2019年元旦,Hanjst/汉吉斯特 正式对外公布。

发表在 -Hanjst/-汉吉斯特, 编程技术, 计算机技术 | 标签为 , , , , , | 留下评论

OpenAI ChatGPT

gMIS吉密斯更新Workflow工作流、FileMgr文件柜及GTAjax等模块

gMIS吉密斯 近期更新了Workflow工作流、FileMgr文件柜及GTAjax等模块,记录于此,备忘备查。北京雾霾持续严重级别,雾霾指数持续300多。翻阅两年前的2016Nov26, 雾霾情况居然相同的严重。

  1. WorkFlow工作流改进更新
    因工作需要,很早的时候就在 gMIS 中增加了一个简易的工作流功能。这次在考虑了多用户协作方面对该功能进行了拓展。
    扩增 Act Options功能,进一步释放操作潜能,在被管理的任意一条数据上,除了常规的“编辑/打印/删除”等,可以允许开发者有针对性的增加任意多的操作动作,这些动作可以通过 xml 绑定到指定的数据表上。
    <actoption>actHrefOne | actHrefTwo | …</actoption>

    Workflow 在 gMIS吉密斯中简称为“todolist/任务管理”, 之前是类似与便签的工作笔记,现在通过 ActOption 增加了 回复 / 转发 等功能,可以为工作流转提供更多便利性。如:

    <actoption>jdo.php::tbl=THIS_TBL,pnskpid=THIS_ID,id=THIS_ID,pnsktriggerbyparent=THIS_triggerbyparent,pnsktriggerbyparentid=THIS_triggerbyparentid,act=’addbycopy’::回复::confirm=0,blank=0 |jdo.php::tbl=THIS_TABLE,pnskpid=THIS_ID,id=THIS_ID,act=’addbycopy’::转交::confirm=0,blank=0</actoption>

    actoption 配置功能标签的增加,将为被管理对象带来更多操作便利,为增加个性化操作提供了一条通道。

  2. 新增文件管理功能FileMgr

    最近在 gMIS 实现了一个简易的Web网盘,可以考虑下载试用。如下是一些操作参考内容。网盘逐渐成为刚需,而且目前市面上有各种各样的网盘服务,限于各种原由,其通用性均差强人意,比如“随时随地跨设备”这样的要求。

    我作为技术“顾问”也多次被寻求类似的简易的网盘解决方案,在 gMIS的过往部署中,也屡次被提及此功能,都是由于“懒”,没有上手弄。这次“出手”成下面这样的gMIS版本的网盘。
    数据表设计为冗余字段 parentid, parentname, pparentname, 其中parentid用于记录上一级目录的名称,适合机器读取操作,parentname用于记录上一级目录的名称,pparentname用于记录当前目录的祖父目录。
    其中, parentname和pparentname都采用了fullpath/全目录的结构设计,适合人读取、理解、使用和接收。

    1)访问路径: Π 首页 → 桌面 & 系统配置 → 文件柜 | 文件柜
    2)上传文件或新建目录
    3)子目录导航、浏览
    4)文件下载/更新,子目录的修改
    当目录名称被修改时,按逻辑同步修改其下所有资源和子目录的目录名称;
    当目录被删除时,按逻辑检查目录下是否非空,当目录下还有内容时,删除目录动作将被拒绝;
    5)其上叠加了很多 gMIS 的各种增强的辅助功能。

    FileMgr 文件柜可以为用户提供了全功能的在线文件管理,轻松实现文件的集中管理、分享、分发、备份等目的。

  3. 升级 GTAjax至最新 5.6 版本
    gMIS 依赖 GTAjax 实现页面局部刷新或者后台通信。这次更新gMIS要解决目标数据表的字段名称为“name”的表单的新增、修改异常问题。

    例如当某个数据表包含有某个字段名称为“name”时,在生成新增HTML表单时,会自动创建如下HTML表单,
    <form name=”gmisForm” id=”gmisForm”>
        <input name=”name” id=”name”/>
        ….
    </form>

    针对上述表单,gMIS 会依照一贯的方法呼叫 GTAjax 进行表单数据递交。

    此时,如果通过 <button name=”submitbtn” type=”submit” onclick=”javascript:doAction(this.form.name);”></button> 对表单的递交进行处理的话, this.form.name 预期返回的是 “gmisForm”, 而如果有一个input元素的名称是“name”时,HMTL form的 this.form.name 会返回一个 input对象。

    GTAjax 是一个单独项目,主要用来处理在页面无刷新的情况下,对页面元素进行局部更新,从而实现更高效地HTTP通信。
    GTAjax 项目开源地址在 -GTAjax

  4. 其他更新与修正
    1)修正了导出数据到MS Office Excel时的UTF BOM指定,增加打开目标数据文件的模式为“wb”;
    2) 更新了文件上传模块,增加更多的上传错误明细显示;
    3) 更新了核心类 MySQLix.class, 增加异常日志打印;
    4)更新了登录模块验证码功能,增加实时校验验证码功能;
    5)改进act/trigger参数传递;
    6)改进 pickup 区域同步刷新机制;
    7)改进 class/pagenavi ,增加 notcontainslist等操作符;
    8)多实例对象共享多数据库配置。在最早的设计中,gMIS 只依赖  gtbl.class 一个全局对象完成对数据的操作,因此在实现对多个数据库进行操作时,只需在 gtbl.class 中进行多数据库的连接配置即可。
    随着 gMIS 的功能的增强,我们增加了越来越多的实例对象,如 IntSiteSearch, Pivot, PickUp 等,如何在这些对象里共享 gtbl.class 的多数据库信息成为需要解决的问题。
    本次引入了全局配置参数 args_to_parent 将 gtbl.class 的共享配置信息传递给 InSiteSearch, Pivot 和 PickUp 等。

-gMIS (general Management Information System) 是一种基于 -GWA2 (General Web Application Architecture) 的通用管理信息系统应用软件,具有可配置的输入和输出接口、开箱即用等特征。
可以在其上构建各种信息管理应用软件系统,如
内容管理系统(CMS), 客户资源管理(CRM), 企业资源计划管理(ERP),
办公自动化系统(OA)等, 以及各种行业应用管理系统软件,如
人力资源管理系统(HR),学生管理,档案管理,旅游管理,图书管理,
商品管理及业务运营支撑系统(BOSS)等等。
实现零代码开发、快速搭建各种管理信息系统(MIS, Management Information System).

-gMIS is a -GWA2 based Management Information System (MIS) software with characteristics like configurable input and output interfaces, open-box-to-use.
Various management application software systems can be built on it, such as
Content Management System (CMS), Customer Resource Management (CRM), Enterprise Resource Planning Management (ERP),
Office automation systems (OA), as well as different industry application management system softwares, such as
Human Resource Management System (HR), Student Management, Archive Management, Tourism Management, Book Management,
Commodity management and business operations support systems (BOSS), etc.
With zero code development, -gMIS can build a set of management information systems (MIS) software in a few minutes.

Lower Costs, 
Better Productivity.
降低成本,
提高效率.

发表在 -gMIS, -GTAjax, 编程技术, 计算机技术 | 标签为 , , , , , , | 4条评论

UfqiNews有福常在Google Books亮月亮科技Apache Softwares

GWA2Perl研发:try-catch无法退出循环、方法传参引用传值及多数据库链接

在使用 GWA2Perl 开发时遇到一些破费周折才发现的 Bug或改进的功能,分析记录如下,备忘。 GWA2 是一套跨语言的网络应用软件开发框架,目前有PHP、Java和Perl版本可供下载选用,也即 GWA2PHP, GWA2Java 和 GWA2Perl。

1. 应用 Tiny::Try 的Catch模块无法执行退出循环的问题


use Tiny::Try
….
foreach my $i(keys %alist){
try{
    # something
}
catch{
    if(aCondition==1){
        next; # cannot?
    }
}
}

此处的 next 无法按预期执行. 改进的措施是,预先顶一个 $tryresult = 0; 然后在成功的时候,将 $tryresult =1; 在 try::catch 执行完毕之后再对 $tryresult 进行判断,以决定是否退出循环. 修改后的代码大致如下。


use Tiny::Try
….
foreach my $i(keys %alist){
my $tryresult = 1;
try{
    # something
}
catch{
    if(aCondition==1){
        next; # cannot?
    }
    $tryresult = 0;
}
if($tryresult == 0){
    next;
}
}

2. Perl方法传递参数应用传值的问题

my %alist = (‘a’=>1, ‘b’=>2);
&functionA(\%alist);
&functionA(%alist); # wrong!
&functionA($alist) # wrong!

my $blist = \%alist;
&functionA($blist);
&functionA(\%blist); # wrong!

Perl的方法参数传递问题,在此前的贴文中进行过相应的讨论,如 -R/H2SP 和 -R/32SJ , 这次重新再三的提及,主要还是由于在Perl的参数传递过程中,极易发生误解,对Perl依靠形式来获取数据类型的做法认识的不够深刻。如给定同一个变量名称,可能表述不同的意思。

$varA = undef; –> 一个普通的未知类型的变量 varA;
$varA[0] –>  一个数组变量 varA ;
$varA{‘a’} –> 一个哈希变量 varA ;
$varA = []; –> 一个hashref变量 varA;

正是这种随意性使得Perl语言的变量掌握起来让人容易出错,再结合传值或者传引用,迷惑性更大。

3. Perloop/Perlobj 面向对象的Perl进行多数据库同时连接的问题

3.1.问题描述
在 GWA2Perl的实现中,对象连接数据库通过 WebApp –> Dba –> Conn –> Driver 的过程( -R/12SL  )。 设若有对象ObjectA,需要连接数据库DatabaseA; 有对象ObjectB,需要连接数据库DatabaseB。
在此设置下,若单独运行实例化的 ObjectA,或者ObjectB均没有问题,或者同时运行ObjectA/ObjectB,同时连接到数据库DatabaseA,也没有问题。 当我们希望同时运行实例化的ObjectA/ObjectB,并分别连接数据库DatabaseA/DatabaseB时,问题就发生了,Perl的运行时环境中,总是留存最后一个活跃的数据库连接信息。
类似的问题并不会在非PerlOOP的环境中产生,如果在通过的函数式编程中,可以通过声明不同的 $dbi 实例来映射到不同的数据库连接上,并保持到一个session执行结束或者手工关闭。比如 $dbiDatabaseA 连接到DatabaseA上,$dbiDatabaseB连接到DatabaseB上。

3.2. 通过对象实例的UniqueId来区别实例
根据对问题的描述,在 PerlOOP中,实例化后的对象共享数据库连接,如果其中以参数的方式带入不同的数据库连接信息,实例化后对象的无法保持数据库信息与具体实例的对应关系。
解决的思路是在 WebApp一层增加如下设施:
1) + getUniqueId
2) + _checkDbConn
其中 1) 是在对象实例化后根据对象 Scalar::Util 的方法 refaddr 来获取对象的唯一 Id号,然后在 WebApp 中,实现对象与数据库信息做绑定;
2) 在 WebApp 中每当进行数据库读写操作时,获取当前实例化对象的 唯一Id,然后从环境变量 %hmf 中获得其绑定的 数据库信息,从数据库对象 $dba 中获得当前活跃的数据库信息,然后对两者做比较,当两者相符时,继续前行;当两者不一致时,重置/切换数据库连接至实例化对象所绑定的数据库上。
也许这是临时解决方案,在后续的PerlOOP中能得到解决,或者在 Perl 6中能够将对象封装的更严密些。

3.3 实例化后的对象根据唯一Id扩展
实现了可以同时操作多个数据库的PerlOOP,GWA2Perl的能力将进一步扩增,其他类似的资源读取均可以实现多源读取,如Session,Cache,File等其他网络资源。
这一问题是第二次碰到,起初遇到时,想到的是在程序中临时切换数据库连接,当其时并没有更好的解决方案,今次深入分析,获得一个可以自动化的持续解决方法,可以实现:
1) 同一个对象在一个时期内,总是持续一致地维持对资源的连接;
2) 不同的对象,拥有不同的资源连接,且可以同时并行。

-GWA2 是”通用网络应用架构( General Web Application Architeture )”,基于 -GWA2 可以轻便构建各种网络应用程序,
包括复杂的在线购物商城、 旅游交易平台、社群或者社交网站和新闻资讯网站等,
也包括各种企事业单位网上门户,在线交互及服务作业系统等.
还可以包括为NativeApp做服务器端支持, 甚至是WebApp的全部.
-GWA2 是为数不多的支持跨开发语言的应用框架,目前支持 -Java, -PHP, -Perl, -Aspx and -Python .

-GWA2 is a “General Web Application Architecture” and based on -GWA2 developers can easily build a variety of network applications,
including complex online shopping malls, travel trading platforms, community or social networking sites and news information sites, etc.
Also the applications include various online portals of enterprises and institutions, online interaction and service operations systems.
Moreover it contains server-side support for NativeApp, or even all of the WebApp.
-GWA2 is one of the web frameworks which provide cross-language support for -Java, -PHP, -Perl, -Aspx and -Python at present.

-GWA2 is E.A.S.Y 
Easy Along, Swift Yield
轻松启动, 快速产出.

发表在 -GWA2, 编程技术, 计算机技术 | 标签为 , , , , | 留下评论

OpenAI ChatGPT