深入 Hyperf:HTTP 服务启动时发生了什么?

当我们创建 Hyperf 项目之后,只需要在终端执行 php bin/hyperf.php start 启动命令,等上几秒钟,就可以看到终端输出的 Worker 进程已启动,HTTP 服务监听在 9501 端口的日志信息。

[INFO] Worker#3 started.  
[INFO] Worker#1 started.  
[INFO] Worker#2 started.  
[INFO] Worker#0 started.  
[INFO] HTTP Server listening at 0.0.0.0:9501  

打开浏览器访问 http://127.0.0.1:9501,不出意外的话,页面会显示 Hello Hyperf,说明 HTTP 服务已经在工作了。那么这是怎么做到的呢?当我们执行启动命令后,Hyperf 是如何让 HTTP 服务启动的?

所以今天这篇文章我会从启动命令开始,给你介绍下 HTTP 服务是如何完成初始化并启动的。通过阅读这篇文章,你可以了解到以下内容:

  • Hyperf 启动时会做哪些初始化操作?
  • HTTP 服务启动时会做哪些初始化操作?
  • HTTP 服务初始化时有哪些关键配置项?

接下来,我们就从 Hyperf 的入口文件开始,了解启动 HTTP 服务的实现思路。

文章会持续修订,转载请注明来源地址:http://her-cat.com/posts/2023/05/15/what-happens-when-hyperf-http-server-starts/

bin/hyperf.php 文件:Hyperf 的入口

在启动命令中,除了 PHP 可执行文件以外,有两个是我们要关注的重点:

  • bin/hyperf.php:Hyperf 的入口文件
  • start:启动命令的参数

先来看一下 bin/hyperf.php 文件,我将该文件的执行逻辑分成了四个阶段。

初始化项目配置信息

在这个阶段中,主要是通过调用一些 PHP 内置函数,完成 PHP 相关的配置初始化,比如运行内存大小限制、错误级别、时区等等。

我们需要注意下在这一阶段定义的两个常量: BASE_PATH 和 SWOOLE_HOOK_FLAGS。

  • BASE_PATH:保存的是 Hyperf 项目所在目录的完整路径,Hyperf 中很多操作都是基于该常量来定位目录和文件的路径。
  • SWOOLE_HOOK_FLAGS:Swoole 采用 Hook 原生 PHP 函数的方式实现协程客户端,该常量保存的是 Hook 的函数的范围,比如套接字、文件、curl 等等。SWOOLE_HOOK_ALL 表示 Hook 所有函数。

我们经常会在 Swoole 相关的资料文档中看到「一键协程化」技术,实际上指的就是在启用协程时传入 SWOOLE_HOOK_ALL 配置项,通过 Hook 所有函数,让项目中会发生 IO 阻塞的代码变成可以协程调度的异步 IO,即一键协程化。

初始化类加载器

在 Hyperf 中,我们可以使用注解减少一些繁琐的配置,还可以基于注解实现很多强大的功能。比如注解注入、AOP 面向切面编程、路由定义、权限控制等等。这些功能能够正常运行,其实都离不开类加载器在初始化过程中的准备工作。

在初始化类加载器过程中,主要会进行以下操作:

  • 收集注解使用信息并完成注解收集器的初始化。
  • 生成代理类,为实现 AOP 及 Inject 注解注入功能做准备工作。
  • 生成运行时缓存,提高框架启动速度。

初始化依赖注入容器

在这个阶段, Hyperf 会先读取预先定义好的依赖关系的配置信息,包括 config/autoload/dependencies.php 配置文件中用户自定义的依赖关系,以及各组件中通过 ConfigProvider 机制定义的依赖关系。将这些初始的依赖关系保存到依赖注入容器中,完成对容器的初始化。

初始化命令行应用

我们回过头来看一下启动命令,你会发现,实际上 Hyperf 本身就是一个命令行应用,而启动命令中的 start 不过是命令行应用的参数,也就是要执行的命令的名字。

在 Hyperf 中有很多内置的命令,比如 start、migrate、gen 等等,当然我们也可以根据自己的需求自定义命令。初始化命令行应用的过程,就是将这些 Hyperf 内置的命令、自定义的命令,注册到命令行应用中的过程。

初始化并启动 HTTP 服务

到了这里,Hyperf 的初始化工作就已经结束了,命令行应用就会开始对启动命令中的参数进行解析,通过参数找到在命令行应用中注册的命令并执行。参数 start 对应的命令类是 StartServer,你可以在 hyperf/server 组件中找到它。

在 StartServer 中,完成了对 HTTP 服务的初始化以及启动操作,包含检查运行环境、读取服务配置文件、初始化 HTTP 服务、启动 HTTP 服务四个步骤,下面我们来了解一下这些步骤中分别做了哪些事情。

检查运行环境

我们知道,Hyperf 目前使用 Swoole 作为底层框架,所以在启动的时候,会先检查是否安装了 Swoole 的扩展,然后再检查是否禁用了 Swoole 的函数短名(short function name),如果没有禁用,就会输出提示信息并终止程序的运行。

读取服务配置

在 Hyperf 中,我们使用 config/autoload/server.php 文件来配置服务信息,详细的字段说明可以查看 Hyperf 官方文档。

其中有两个字段需要注意,分别是 server.typeserver.servers.type,很多人不太清楚这两个配置项的作用和区别,下面我们来了解一下。

Swoole 提供了异步和协程两种风格的服务端,下面是两者的不同之处。

  • 协程风格的服务端可以在运行时动态创建、销毁,而异步风格的服务端在启动后就不能再对它进行操作了。
  • 协程风格的服务端对连接的处理是在单独的协程中完成,与客户端的交互是顺序性的,而异步风格的服务端无法保证顺序性。

Hyperf 作为上层框架,当然要支持这两种风格的服务端,同时还要考虑到扩展性,方便后续接入其它风格的服务端。

所以 Hyperf 在设计之初做了一层抽象,定义了一个 ServerInterface 接口,在接口中定义了三个常量,作为服务类型的枚举值。用于在配置文件中通过 server.servers.type 配置项设置服务的类型。同时,还定义了构造函数、初始化、启动三个方法。

interface ServerInterface
{    
	// HTTP 服务  
    public const SERVER_HTTP = 1;    
    // Websocket 服务  
    public const SERVER_WEBSOCKET = 2;    
   // TCP 服务  
    public const SERVER_BASE = 3;    
   // 构造函数  
    public function __construct(ContainerInterface $container, LoggerInterface $logger, EventDispatcherInterface $dispatcher);    
   // 初始化  
    public function init(ServerConfig $config): ServerInterface;    
   // 启动  
    public function start(): void;
}  

Hyperf 不仅实现了基于 Swoole 的两种风格的服务端,还实现了基于 Swow 的服务端。

  • Hyperf\Server\Server:异步风格的服务端,由 Swoole 提供底层支持。
  • Hyperf\Server\CoroutineServer:协程风格的服务端,由 Swoole 提供底层支持。
  • Hyperf\Server\SwowServer:协程风格的服务端,由 Swow 提供底层支持。

我们可以通过 server.type 配置项,来决定使用哪种风格的服务端用于运行各种类型的服务。当然,你也可以通过实现 ServerInterface 接口,自定义其它类型的服务端。

初始化 HTTP 服务

通过上面的内容你可以知道,在运行 Hyperf 的时候,只能使用一种服务端,但是可以运行多个不同类型的服务,比如 HTTP 服务、Websocket 服务等等。为了便于说明,我会使用异步风格服务端给你介绍初始化 HTTP 服务的过程。

初始化 HTTP 服务的操作,是在 ServerFactory::configure 方法中完成的,主要可以分为两个步骤。

  • 第一步,将配置信息解析成 ServerConfig 对象。

在这一步骤中,主要是将配置文件中数组形式的配置信息,解析成 ServerConfig 对象。

class ServerConfig implements Arrayable
{
    public function __construct(protected array $config = [])
    {
	    // 将各种类型的服务解析成 Port 对象
        $servers = [];
        foreach ($config['servers'] as $item) {
            $servers[] = Port::build($item);
        }

		// 将其它类型的配置都保存到对象中
        $this->setType($config['type'] ?? Server::class)
            ->setMode($config['mode'] ?? 0)
            ->setServers($servers)
            ->setProcesses($config['processes'] ?? [])
            ->setSettings($config['settings'] ?? [])
            ->setCallbacks($config['callbacks'] ?? []);
    }
}

当没有设置服务端的类型时,默认使用 Hyperf\Server\Server,即异步类型的服务端。

  • 第二步,调用 Hyperf\Server\Server::init 方法完成对 HTTP 服务的初始化。

在这一步骤中,会调用 ServerFactory::getServer 方法,根据 ServerConfig 对象中的 type 属性实例化出对应的服务端对象,即 Hyperf\Server\Server 对象。在 Hyperf\Server\Server 对象中,定义了一个 server 属性,用于保存 Swoole 异步风格服务器对象。在 Swoole 异步风格的服务端中,有以下三种类型的服务器:

  • Swoole\Server:TCP 服务器,是所有异步风格服务器的基类。
  • Swoole\Http\Server:HTTP 服务器。
  • Swoole\WebSocket\Server:WebSocket 服务器。

在 init 方法中,会根据 server.servers.type 配置项的值(即 ServerInterface 接口中的常量),实例化出相应的服务器对象,并保存到 server 属性中。

这里会有一个问题,在 Hyperf\Server\Server 对象中只有一个 server 属性,但是,在 server.servers 配置项中,我们可以配置多个不同类型的服务,那么是如何支持运行多个服务的呢?

这里就跟 Swoole 的服务器实现有关,Swoole 的异步风格服务器可以通过调用 addListener 方法监听多个端口,每个端口都可以设置不同的协议处理方式。这样就实现了一个服务器对象,同时运行多个不同类型的服务。

下面我们来看一下 init 方法的主要逻辑。

首先,在 init 方法中会先调用 ServerFactory::sortServers 方法,对需要启动的服务按照类型 Websocket、HTTP、TCP 的顺序进行排序。

然后,依次遍历这些服务,完成对每个服务的初始化。循环中包括两个分支:

  • 第一个分支对应了 server 属性未初始化的情况。 此时,会调用 makeServer 方法实例化出相应的服务器对象,然后为服务器对象注册事件回调函数,最后初始化服务器对象的配置信息。
  • 第二个分支对应了 server 属性已初始化的情况。 此时,会调用服务器对象的 addListener 方法,增加一个端口并返回子服务器对象,然后为子服务器对象注册事件回调函数,最后初始化子服务器对象的配置信息。

在 makeServer 方法中,会根据服务类型实例化出相应的服务器对象,下面代码展示了这部分的逻辑,你可以看下。

switch ($type) {  
    case ServerInterface::SERVER_HTTP:  
        return new Swoole\Http\Server($host, $port, $mode, $sockType);  
    case ServerInterface::SERVER_WEBSOCKET:  
        return new Swoole\WebSocket\Server($host, $port, $mode, $sockType);  
    case ServerInterface::SERVER_BASE:  
        return new Swoole\Server($host, $port, $mode, $sockType);  
}

Swoole 提供了很多事件,比如 workerStart 工作进程启动后的事件、request 收到请求后的事件,这些事件在 Hyperf\Server\Event 中都有相应的常量。

在 Hyperf 中,有三种事件回调函数的配置,分别是全局事件、服务事件、默认事件。

  • 全局事件:使用 server.callbacks 配置项设置全局的事件的回调函数。
  • 服务事件:使用 server.servers.callbacks 配置项为每一个服务单独设置事件的回调函数。
  • 默认事件:在 Hyperf\Server\Server 对象的 defaultCallbacks 方法中配置了一些默认的事件的回调函数。

这些配置优先级是:服务事件 > 全局事件 > 默认事件。下面的代码展示了注册事件的回调函数的核心逻辑。

// 按照优先级获取配置的所有事件及其回调函数
$callbacks = array_replace($this->defaultCallbacks(), $config->getCallbacks(), $callbacks);
foreach ($callbacks as $event => $callback) {
	// 非 Swoole 事件,直接跳过
    if (! Event::isSwooleEvent($event)) {
        continue;
    }
    ...
    // 为服务器对象注册该事件的回调函数
    $server->on($event, $callback);
}

启动 HTTP 服务

在启动 HTTP 服务之前,会执行以下代码设置一键协程化 Hook 的函数范围,swoole_hook_flags 函数的返回值就是 SWOOLE_HOOK_FLAGS 常量的值,即 SWOOLE_HOOK_ALL。

Coroutine::set(['hook_flags' => swoole_hook_flags()]);

接着会调用 ServerFactory::start 方法启动服务,在该方法中,直接调用 Hyperf\Server\Server 的 start 方法启动 Swoole 服务器。

当 Swoole 服务器启动后,会执行注册在服务器对象的 Event::ON_WORKER_START 事件的回调函数 WorkerStartCallback::onWorkerStart。

在 onWorkerStart 方法中,输出 Worker#{$workerId} started. 日志信息,并通过事件分发器分发 AfterWorkerStart 事件,在该事件的监听器 AfterWorkerStartListener 中,输出 HTTP Server listening at 0.0.0.0:9501 日志信息。

到这里,HTTP 服务就已经启动了。

总结

在这篇文章中,我们通过 bin/hyperf.php 文件,了解了 Hyperf 在初始化框架时会执行哪些操作。接着,又通过 StartServer 了解了 HTTP 服务在启动过程中的四个步骤。其中,HTTP 服务的初始化是整个启动过程中的关键步骤,你可以配合源码进一步了解 Hyperf 的设计和实现思路。

尽管本文的主题是 HTTP 服务,但实际上,无论是 WebSocket服务、TCP服务还是其他类型的服务,这些服务的启动过程与 HTTP 服务的启动过程大同小异。

因此,掌握 HTTP 服务的启动过程,不仅有助于你了解 HTTP 服务的运行细节,还有助于你了解 Hyperf 以及其它类型服务的运行细节。当你遇到问题时,可以按照启动过程中的步骤逐步检查,从而帮助你更快地解决问题。

博客地址:她和她的猫,欢迎关注。
本文转载于网络 如有侵权请联系删除

相关文章

  • Hadoop伪分布式安装【翻译自Hadoop1.1.2官方文档】

    1.Hadoop支持的平台: GNU/Linux平台是一个开发和生产的平台.hadoop已经被证明可以在GNU/Linux平台不是2000多个节点。win32是一个开发平台,分布式操作还没有在win32系统上很好的测试,所以它不被作为生产环境。 2.安装hdoop需要的软件:    linux和windows下安装hadoop需要的软件:   2.1从sun官网下载的1.6的jdk必须被安装.   2.2ssh必须被安装andssh协议必须使用hadoop脚本用来管理远程的hadoop进程。   2.3windows环境下,额外需要安装下面软件:Cygwin-运行上述软件必须安装的shell环境。3.安装软件:如果你的集群没有必要的软件,那么你必须安装它们在unbuntulinux上执行命令如下:$sudoapt-getinstallssh $sudoapt-getinstallrsync在Windows环境下,如果你安装cywin的话,你不必安装上述软件,只需要在安装cygwin的时候选择相关的软件包即可。openssh-theNetcategory 4.下载hadoop地址: ht

  • 关于 SAP Spartacus Loader Meta Reducer 的用途

    为了给用户更好的反馈,基于他们的行为,我们经常需要保留诸如“正在加载购物车”、“获取用户地址失败”等信息。对于每个单独的应用程序状态,我们必须将元数据放在旁边。分别用于购物车、用户信息、产品数据等。在所有这些地方手动实现这个逻辑会导致在整个代码库中针对同一问题有不同的解决方案。这就是在spartacus中创建loaderReducer的原因。这个reducer标准化了整个状态树(statetree)中的元数据处理。您可以在树的任何深度、任何需要的地方使用它。除了reducer,我们还提供actions和selectors的实用程序。一个例子:在app.module.ts里插入如下代码:exportclassAppModule{ constructor(privateconfig:DebugConfig, privateactions$:Actions){ //console.log('Jerryconfig:',this.config); this.actions$.pipe( ofType(CartActions.LOAD_CART), map((action:C

  • 宝塔面板上的安装Nginx的配置路径问题

    虽说装上宝塔面板确实省下了安装软件时不必要的麻烦,问题是学过一点Nginx或Apache,就不需要宝塔来创建网站了。关于在宝塔上安装了Nginx后,找不到Nginx对应网站的配置文件,其实一直在如下路径中 如果是直接安装Nginx,没有用到宝塔面板来装,默认路径可以放在/usr/nginx下,这样就可以随便来配置网站相关的信息了。如:网站:http://pt.xdr630.top/ 配置pt.xdr630.top.confserver { listen80; server_namept.xdr630.top; indexindex.phpindex.htmlindex.htmdefault.phpdefault.htmdefault.html; root/www/wwwroot/pt.xdr630.top; #SSL-STARTSSL相关配置,请勿删除或修改下一行带注释的404规则 #error_page404/404.html; #SSL-END #ERROR-PAGE-START错误页配置,可以注释、删除或修改 error_page404/404.html; error_pag

  • 有效粘性阻尼使腿式运动的形态计算成为可能(CS RO)

    肌肉模型和动物观察表明,物理阻尼有利于稳定。尽管如此,在柔顺的机器人腿运动中,只有少数机械阻尼的实现。目前还不清楚如何利用物理阻尼来完成运动任务,而它作为无传感器、自适应力和负功执行器的优势是有希望的。在简化的数值支腿模型中,我们研究了地面扰动下垂直下落时粘性阻尼和库仑阻尼的能量耗散。一个平行弹簧减振器在着陆和中间站姿之间接合,其减振器在中间站姿和起飞期间自动分离。我们的模拟结果表明,需要一个可调的粘性阻尼器。在硬件上,我们探索了有效的粘性阻尼和可调性,并量化了耗散能量。我们测试了两个机械的、安装在腿上的减震机构:一个商用液压减震器和一个定制的气动减震器。气动阻尼器利用带有可调孔板的滚动隔膜,在允许可调阻力的同时,将库仑阻尼效应降至最低。实验结果表明,腿式液压阻尼器表现出最有效的粘滞阻尼。与数值模型中调整阻尼参数不同,调整孔板设置不会导致每滴耗散能量的实质性变化。因此,我们还强调了在实际腿碰撞过程中表征物理阻尼器的重要性,以评估其对柔顺腿运动的有效性。原文题目:EffectiveViscousDampingEnablesMorphologicalComputationinLeggedL

  • 最新版针对RNA-seq数据的GATK找变异流程

    RNA-seq标准分析,我们已经讲解的太多了,表达矩阵到差异分析等下游生物学注释都没有啥新颖之处,融合基因和可变剪切算是出彩的地方,如果加上GATK找变异流程就更棒了,反正都使用了star软件进行序列比对拿到bam文件了。如果你简单谷歌搜索关键词:gatkbestpracticespipelinerna-seq会搜索到大量过期的教程:2014年5月6日-BestPracticesworkflowforRNAseqhttps://gist.github.com/PoisonAlien/c6c03539cf4b1ac41cf12016年10月27日-https://www.biostars.org/p/219281/2016年10月17日-https://gatkforums.broadinstitute.org/gatk/discussion/3892/the-gatk-best-practices-for-variant-calling-on-rnaseq-in-full-detail2017年3月17日-2017Mar17.doi:10.12688/wellcomeopenres.1

  • 通过Docker安装JIRA和Confluence(转)

    需要工具如下:Docker镜像GithubCrack工具Github采用以上工具,理论上可以破解几乎全部版本。1安装mysql5.7#启动容器mysql dockerrun--namemysql\ --restartalways\ -p3306:3306\ -eMYSQL_ROOT_PASSWORD=zagame10086\ -vdata_mysql_vol:/var/lib/mysql\ -vconf_mysql_vol:/etc/mysql/conf.d\ -vdata_backup_vol:/backup\ -dmysql:5.7复制1.1配置数据库MySQL所使用的配置文件my.cnf核心参数:[client] default-character-set=utf8 [mysql] default-character-set=utf8 [mysqld] character_set_server=utf8 collation-server=utf8_bin transaction_isolation=READ-COMMITTED复制需要注意的是,Confluence需要使用ut

  • iKcamp新书上市《Koa与Node.js开发实战》

    内容摘要Node.js10已经进入LTS时代!其应用场景已经从脚手架、辅助前端开发(如SSR、PWA等)扩展到API中间层、代理层及专业的后端开发。Node.js在企业Web开发领域也日渐成熟,无论是在API中间层,还是在微服务中都得到了非常好的落地。本书将通过Web开发框架Koa2,引领你进入Node.js的主战场! 本书系统讲解了在实战项目中使用Koa框架开发Web应用的流程和步骤。第1章介绍Node.js的安装、开发工具及调试。第2章和第3章介绍搭建Koa实战项目的雏形。第4章详细介绍HTTP基础知识及其实战应用。第5章介绍MVC、模板引擎和文件上传等实用功能。第6~8章介绍数据库、单元测试及项目的优化与部署。第9~13章介绍从零开始搭建时下火爆的微信小程序前端及后台管理应用的全部过程,以及最终的服务器部署,包括HTTPS、Nginx。 本书示例丰富、侧重实战,以完整的实战项目贯穿全部章节,并提供书中涉及的所有源码及部分章节的配套视频教程,将是前端开发人员立足新领域和后端开发人员了解Node.js并使用Koa2开发Web应用的得力助手。前言Node.js诞生于2009年,到本书出

  • .htaccess文件用法收集整理

    1.时区设置 有些时候,当你在PHP里使用date或mktime函数时,由于时区的不同,它会显示出一些很奇怪的信息。下面是解决这个问题的方法之一。就是设置你的服务器的时区。你可以在这里找到所有支持的时区的清单。 1.SetEnvTZAustralia/Melbourne 2.搜索引擎友好的301永久转向方法 为什么这是搜索引擎友好的呢?因为现在很多现代的搜索引擎都有能根据检查301永久转向来更新它现有的记录的功能。 1.Redirect301http://www.aqee.net/homehttp://www.aqee.net/  3.屏蔽下载对话框 通常,当你下载东西的时候,你会看到一个对话框询问你是保持这个文件还是直接打开它。如果你不想看到这个东西,你可以把下面的一段代码放到你的.htaccess文件里。 1.AddTypeapplication/octet-stream.pdf  2.AddTypeapplication/octet-stream.zip  3.AddTypeapplication/octet-stream.mov  4.省去www前缀SEO的一个原则是,确保你

  • 一条简单的报警信息发现的oracle bug(r8笔记第42天)

    系统中有这样一条报警信息,看似比较简单,但是引起了我的注意,主要原因是因为这是一个10gR2的备库,备库如果出现这样的问题,看起来似乎是在归档删除上存在一些问题。 [DB监控系统]_ora_test_s2_yangjr@10.127.2.133_报警 ZABBIX-监控系统: ------------------------------------ 报警内容:Freediskspaceislessthan20%onvolume/opt ------------------------------------ 报警级别:PROBLEM ------------------------------------ 监控项目:Freediskspaceon/opt(percentage):9.99% ------------------------------------ 报警时间:2016.03.17-02:54:03 于是做了初步的检查,查看磁盘空间,发现数据分区的空间使用率已经剩下差不多9%了。 [@test.cyou.comarch]#df-h FilesystemSizeUsedAva

  • 前端技能图谱

    基础HTML/CSSJavaScriptNode.js正规表达式数据格式(如JSON、XML)RESTfulAPI交互(如jQueryAjax,FetchAPI,ReactiveX)命令行中级ES6/CoffeScript/TypeScriptSCSS/SASSCSS3HTML语义化面向对象编程函数式编程MVC/MVVM/MV*矢量图形/矢量图形动画(如SVG)单页面应用安全性(如跨域)授权(如HTTPBasic、JWT等等)工程化代码质量(如JSLint/ESLint/TSLint/CSLint)代码分析(如CodeClimate)测试覆盖率构建系统(gulp、grunt、webpack等等)自动构建(脚本)兼容性跨浏览器测试(Chrome,IE,Firefox,Safari等等)跨平台测试(Windows、GNU/Linux,MacOS等等)跨设备测试(Desktop,Android,iOS,WindowsPhone)跨版本测试(同一个浏览器的不同版本)前端特定CSS/CSS3动画JavaScript动画Web字体嵌入Icon字体图形和图表CSSSprite(如glue)DOM操作

  • ROR学习笔记(1):Rails 2快速创建GRUD应用

    机器上没安装ROR开发环境的朋友,请先参看rubyonrails+mysql开发环境搭建 架好环境注:ROR的经典著作“Web开发敏捷之道--应用Rails进行敏捷Web开发”目前中文的只有第二版,作者写书的环境是rails1.x,现在rails的版本已经更新至2.3.5,很多东西已经变了,如果参考第二版的书上一步步来做的话,根本做不下去。(目前该书已经出了第三版,只不过国内暂时尚无翻译版本,http://hlee.javaeye.com/blog/363605 这里可以下载该书英文电子版)以下操作命令,均在windows命令行模式下完成 1.进入工作目录(本例为d:\mydoc\ror\)d:cdmydoc\ror2.创建带mysql的rails项目:depot(项目名称可随便起,不一定要用depot)D:\MyDoc\Ror\depot>rails-dmysqldepot3.编辑database.yml,修改username与password,同时在mysql中把database.yml对应的数据库建好(注意编码建议选择为utf8)注意:mysql不要安装最新的5.1版本,建

  • 带有CSS3的动画3D条形图

    关于如何使用CSS创建动画三维条形图的教程。这一切都是从一个小实验开始的,这个实验受到了来自Nettuts+的教程的启发,它展示了如何使用CSS,图像和JavaScript将3D条形图嵌入到HTML页面中。在阅读完教程之后,我挑战自己将这个想法变成纯粹的CSS,看看我能做多少。最初的挑战是创造一个经典的半透明的6方框3D盒子。最后的挑战是创建一个完整的三维条形图,我们将在本教程中创建。你可以看看我以前做过这里。请注意:本教程的结果只能在支持相应CSS属性的浏览器中按预期方式工作。我们写下一些关键的要求。图表应该是背景无关自适应(独立于条数)可扩展(就像矢量图形)轻松定制(颜色,大小和比例)规划阶段是任何项目中最重要的部分。所以让我们制定一个计划。在实际编写代码之前,我通常会写下所有可能遇到的挑战,并在一个特定的项目中考虑我所能想到的解决方案,并重复这个过程直到我看到一个看起来像是可以执行的策略。下面是我为这个项目提出的解决方案的挑战列表:挑战#1-一个可移动的内部块的酒吧我们知道:一个酒吧应该被表示为由六面组成的三维盒子内块应能在运动中垂直移动。应该有一个选项来隐藏块。我们需要什么:1

  • eShopOnContainers 知多少[7]:Basket microservice

    引言 Basketmicroservice(购物车微服务)主要用于处理购物车的业务逻辑,包括: 购物车商品的CRUD 订阅商品价格更新事件,进行购物车商品同步处理 购物车结算事件发布 订阅订单成功创建事件,进行购物车的清空操作 架构模式 如上图所示,本微服务采用数据驱动的CRUD微服务架构,来执行购物车商品的维护操作。并使用Redis数据库进行持久化。 这种类型的服务在单个ASP.NETCoreWebAPI项目中即可实现所有功能,该项目包括数据模型类、业务逻辑类及其数据访问类。其项目结构如下: 核心技术选型: ASP.NETCoreWebAPI EntityFrameworkCore Redis Swashbuckle(可选) Autofac Eventbus Newtonsoft.Json 实体建模和持久化 该微服务的核心领域实体是购物车,其类图如下: 其中CustomerBasket与BasketItem为一对多关系,使用仓储模式进行持久化。 通过对CustomerBasket对象进行json格式的序列化和反序列化来完成在redis中的持久化和读取。 以单例模式注入

  • Spring MVC中返回JSON数据的几种方式

    我们都知道SpringMVC的Controller方法中默认可以返回ModeAndView和String类型,返回的这两种类型数据是被DispatcherServlet拿来给到视图解析器进行继续处理返回页面的,而不是直接返回给客户端的。有时候我们需要发请求后让服务端直接返回一些数据,不再经过DispatcherServlet,这个时候通常有两种方式: 1.使用@ResponseBody注解   该注解的作用是把方法返回结果转成json或xml格式并进行返回,不管要返回什么类型的数据,是String还是一个对象,只要是需要请求后想直接返回Json或xml类型的数据,那么就都可以使用这个注解。   注意:这里@ResponseBody的格式转换是将class类型如一个javabean,map,list等类型进行转换,转换后的结果是一个json对象,如果想返回一个json字符串,那么就需要自己手动处理成json串的格式,json串也就是一个String,这时@ResponseBody就只起到把这个String返回的作用,示例代码如下: @RequestMapping("/jsontest")

  • ASP.NET Core 1.0 入门——Application Startup

    ASP.NETCore1.0入门——ApplicationStartup¶警告您当前查看的页面是未经授权的转载!如果当前版本排版错误,请前往查看最新版本:http://www.cnblogs.com/qin-nz/p/aspnet5-application-startup.html 提示 更新时间:2016年01月20日。 Startup类¶ 在ASP.NETCore1.0中,Startup类是一个应用的入口点,我们可以为不同环境配置不同的内容。 编译器会查找项目文件夹下的所有*.cs文件进行编译,而运行时会寻找所有命名空间下类名为Startup的类作为启动方式。 注解 可以通过设置project.json文件选择需要(或不需要)编译的文件和文件夹;也可以设置在不同的程序集中搜索Startup类。 Startup类必须定义一个Configure方法,也可以同时定义一个ConfigureServices方法。 Startup类的构造函数¶ 构造函数,可以帮我们设置配置文件的位置,比如下面的代码设置了appsettings.json。 publicStartup(IHosting

  • 做Web自动化前,你必须掌握的几个技能

    每天进步一点点,关注我们哦,每天分享测试技术文章 本文章出自【码同学软件测试】 码同学公众号:自动化软件测试,领取资料可加:magetest 码同学抖音号:小码哥聊软件测试 学习web自动化的前提条件:手工测试(了解各种测试的知识)、学习编程语言、学习Web基础、学习自动化测试工具、学习自动化测试框架、需要掌握前端的一些知识,无论学习语言还是前端知识,都是为了接下来的脚本和框架做铺垫,本篇文章介绍下前端基础知识   网页基础(HTML、CSS),web前端三大核心技术 HTML:负责网页架构 CSS:负责网页的样式,美化 JS:负责网页行为       01常见的HTML标签   HTML是描述网页的一种语言 HTML指的是超文本语言,不是编程语言,是一种标记语言 HTM使用标签来描述网页   案例:txt文本转html格式 <h1>这是第一个段落文件</h1> <h2>这是第二个段落文件</h2> <imgsrc="C:\User

  • bzoj1251 序列终结者(splay)

    人生第一发splay,写得巨丑,最后忘记了push_down以后要将子节点maintain 9k代码不忍直视 1#defineNDEBUG 2#include<cstdio> 3#include<cassert> 4#include<climits> 5#include<cstdlib> 6#include<algorithm> 7#ifndefNDEBUG 8#defineint_out(_a_)printf(#_a_"=%d\n",_a_); 9#else 10#defineint_out(_a_){} 11#endif 12classsplay_tree{ 13private: 14structnode; 15node*link_node(node*constfather,node*constchild,constintd); 16mutablenode*root; 17staticnode*constnil; 18node*kth(constintk); 19node*max(); 20public: 21splay

  • 基于jQuery商城网站全屏图片切换代码

    基于jQuery商城网站全屏图片切换代码。这是一款商城网站全屏多张图片滑动切换代码。效果图如下: 在线预览    源码下载 实现的代码。 html代码: <divclass="slides"> <divclass="slideInner"> <ahref="#"style="background:url(img/slide1.jpg)no-repeat;"> <divclass="moveElemimg1"rel="0,easeInOutExpo"> <imgsrc="img/slide1p1.png"/> </div> <divclass="moveElemimg2"rel="150,easeInOutExpo"> <imgsrc="img/slide1p2.png"/> </div> </a><ahref="#"style="background:url(img/slide2.jpg)no-repeat">

  • jquery的事件机制

    jquery的事件机制 一.简单的注册方式 缺点:一次只能注册一个事件(但可以通过.click链式调用继续调用) 例子:$(‘div’).click(function(){               console.log(‘aaa’);    }) 二.bind方式 优点:可以同时注册多个事件 缺点:不方便,新增的元素标签没有事件 bind传个对象不会被覆盖 例子:$(‘div’).bind(function(){               click:function(){console.log(‘点击事件’)},               mouseover:f

  • .NET Core 2.0 项目的智能提示是英文,改成中文的解决方案

    截至目前为止(2017.09.21),Microsoft官方并没有提供.NETCore2.0正式版的多语言安装包。 因此,在VisualStudio2015Update3和VisualStudio2017中,使用.NETCore2.0作为目标框架的项目,编写代码时,智能提示的结果显示时英文的。 如何改成简体中文或其它语言(例如繁体中文)呢?   我知道.NETCore2.0的智能提示文件路径在C:\ProgramFiles\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0目录下。 同时用Everything搜索工具,看到.NETStandard1.0, .NETStandard1.3, .NETStandard1.6,"netcore50"这几个版本都是有简体中文的智能提示文件。 使用Everything的搜索语法: folder:"C:\ProgramFiles(x86)\MicrosoftSDKs\NuGetPackages""\ref\netst

  • Hibernate Criteria 查询使用

    转载 http://blog.csdn.net/woshisap/article/details/6747466  Hibernate设计了CriteriaSpecification作为Criteria的父接口,下面提供了Criteria和DetachedCriteria。  Criteria和DetachedCriteria的主要区别在于创建的形式不一样,Criteria是在线的,所以它是由HibernateSession进行创建的;而DetachedCriteria是离线的,创建时无需Session,DetachedCriteria提供了2个静态方法forClass(Class)或forEntityName(Name)进行DetachedCriteria实例的创建   Spring的框架提供了getHibernateTemplate().findByCrite(detachedCriteria)方法可以很方便地根据DetachedCriteria来返回查询结果。    Cr

相关推荐

推荐阅读