0%

Pimpl(pointer to implementation, 指向实现的指针)是一种常用的,用来对“类的接口与实现”进行解耦的方法。这个技巧可以避免在头文件中暴露私有细节(见下图 1),因此是促进 API 接口与实现保持完全分离的重要机制。但是 Pimpl 并不是严格意义上的设计模式(它是受制于 C++ 语言特定限制的变通方案),这种惯用法可以看作桥接设计模式的一种特例。

图 1: Pimpl 惯用法:这里的公有类拥有一个私有指针,该指针指向隐藏的实现类

在类中使用 Pimpl 惯用法,具有如下优点:

  • 降低耦合
  • 信息隐藏
  • 降低编译依赖,提高编译速度
  • 接口与实现分离

为了实现 Pimpl,我们先来看一种普通的类的设计方法。

阅读全文 »

Spring Boot 提供了非常优雅地使用多线程执行任务的方式,本文说明 Spring Boot 项目如何利用 ThreadPoolTaskExecutor 来使用多线程。

创建 Spring Boot 项目

使用 IntelliJ Idea 创建向导创建一个 Spring Boot 项目,或者在 Spring 官网创建一个 Spring Boot 项目,地址:https://start.spring.io/。由于创建过程比较简单,此处不再赘述。
其中,pom.xm 文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>me.leehao</groupId>
<artifactId>async-method</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>async-method</name>
<description>Demo project for Async Method</description>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
阅读全文 »

OpenResty 是一款基于 Nginx 和 Lua 的高性能 Web 框架,可以方便地基于 Nginx 进行二次开发,以实现超高并发 Web 网关,Web 服务等。

本文讲述如何在 Linux 安装和使用 OpenResty。

安装 OpenResty

OpenResty 官方提供源代码编译安装以及二进制包安装方式,本文采用源代码编译安装方式。有关二进制包安装方式,可以参考链接 https://openresty.org/cn/linux-packages.html

在 OpenResty 下载页面 下载最新版本的 OpenResty,这里笔者下载的是 openresty-1.19.3.1.tar.gz

然后依次执行命令:

1
2
3
4
5
tar zxvf openresty-1.19.3.1.tar.gz
cd openresty-1.19.3.1
./configure
make
make install

注意执行 make install 需要 root 权限。
可以看到 OpenResty 被默认安装到了 /usr/local/openresty/ 目录。

启动 Nginx

阅读全文 »

最近在研究如何利用 Nginx 实现高性能网关,这里记录一下开发 Nginx 扩展模块 Hello World。

编译安装 Nginx

下载 Nginx 源代码,解压,进入源代码目录:

1
2
3
wget http://nginx.org/download/nginx-1.13.10.tar.gz
tar zvxf nginx-1.13.10.tar.gz
cd nginx-1.13.10

编译,安装 Nginx 到指定目录:

1
2
3
./configure --prefix=/home/lihao/code/nginx/nginx-1.13.10/bin
make
make install

configure 命令中使用了参数 --prefix=/home/lihao/code/nginx/nginx-1.13.10/bin 是指将 Nginx 安装到目录 /home/lihao/code/nginx/nginx-1.13.10/bin

修改 /home/lihao/code/nginx/nginx-1.13.10/bin/conf/nginx.conf,调整 Nginx 监听端口为 5123

1
2
3
server {
listen 5123;
server_name localhost;

启动 Nginx:

1
2
cd /home/lihao/code/nginx/nginx-1.13.10/bin
./sbin/nginx
阅读全文 »

WebService 对外提供 SOAP 接口,SOAP 接口基于 HTTP + XML,因此,可以使用 Nginx 作用 WebService 的反向代理,以实现 WebService 请求的负载均衡功能。

本文使用 docker-compose 部署 nginx,有关 docker-compose 的使用,可以参考 《Docker Compose 入门教程》

文件目录结构如下:

1
2
3
4
5
6
7
.
├── conf.d
│ └── ksb.conf
├── docker-compose.yml
└── log
├── access.log
└── error.log

其中,

  • ksb.conf:nginx 的 server 配置文件
  • docker-compose.yml:docker-compose 使用
  • access.log:nginx 访问日志
  • error.log:nginx 异常日志

docker-compose.yml 文件:

阅读全文 »

HTTP/2 具有以下的特性:

  • 采用二进制传输数据
  • 基于流的多路复用
  • 头部压缩
  • 服务端推送

由于 HTTP/2 可以提升网站访问速度,因此,本人决定对个人站点 Leo 的博客 进行 HTTP/2 升级改造。

leehao.me 网站采用 Ngninx + Hexo + NexT 实现,有关部署细节可以参考之前的文章 《在阿里云部署 Hexo 网站》 以及 《Hexo 网站配置免费阿里云证书》

Nginx 从版本 1.9.5 支持 HTTP/2,因此,为使网站支持 HTTP/2,只需要对 nginx 配置进行调整。先查看 Nginx 版本:

1
nginx -v

输出:

nginx version: nginx/1.12.2

说明 nginx 版本已符合要求。查看 nginx 是否已安装 http 2 模块:

1
nginx -V

可以看到 --with-http_v2_module 模块输出:

…–with-http_v2_module…

查看 openssl 版本:

1
openssl version
阅读全文 »

文章 CMake 语言 15 分钟入门教程 介绍了 CMake 语言的基础知识,本文在此基础上,进一步说明说明如何利用 CMake 生成 Makefile,并实现编译安装功能。

CMake 除了可以生成 Makefile 外,还可以生成以下 IDE 的编译文件:

  • Xcode
  • Visual Studio
  • CodeBlocks
  • Eclipse

CMake 生成可执行文件

先来看如何利用 CMake 编译单个 .cpp 源文件。需要编译的 main.cpp

1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;

int main()
{
cout << "hello" << endl;
return 0;
}

创建 CMakeLists.txtCMakeLists.txtmain.cpp 处于同一目录。

1
2
3
4
5
6
7
cmake_minimum_required(VERSION 2.8)

project(hello)

add_executable(hello main.cpp)

install(TARGETS hello DESTINATION bin)
阅读全文 »

Gitlab 集成了 CI / CD (Continuous Integration,持续集成 /
Continuous Delivery,持续交付)功能。下图是 gitlab 官网上有关 ci / cd 各阶段的图示:

本文重点讲述如何利用 gitlab 实现 c++ 项目的持续集成。

安装 gitlab runner

为了利用 gitlab 实现 ci / cd,需要安装 gitlab runner,gitlat runner 用于执行 ci / cd 任务。Gitlab runner 可以部署在与 gitlab 不同的机器,本文采用 docker 方式安装 gitlab runner。

Gitlab runner 的 docker-compose.yml 文件如下:

阅读全文 »

cmake 是一个跨平台的编译安装工具,可以用简单的语句来描述所有平台的编译安装过程。

本文介绍 cmake 的基础语法。

第一个例子

使用任意的文本编辑器,输入:

1
message("Hello world!") 

然后保存为 hello.txt 文本文件,执行:

1
cmake -P hello.txt

输出:

Hello world!

所有变量都是字符串

在 cmake 中,所有变量都是字符串。可以使用 ${} 来引用一个变量。例如,修改 hello.txt

1
message("Hello ${NAME}!") 

然后在执行 cmake 命令时对变量 NAME 进行定义:

阅读全文 »

Dubbo 是一款微服务框架,提供高性能 RPC 通信,服务发现,流量管理等服务治理能力,提供构建大规模微服务集群所需的整套解决方案。

本文讲述如何利用 Dubbo 快速构建一个完整的服务端 - 客户端程序,包括基于 XML,注解和 API 的方式实现一个 Dubbo 的 demo。

配置开发环境

本文使用 IntelliJ IDEA 作为 Dubbo 应用程序开发的 IDE。

安装 ZooKeeper

Dubbo 推荐使用 ZooKeeper (下文简称为 zk)作用注册中心,为简单起见,本文搭建一个单机版的 zk 以供 Dubbo 应用程序使用。有关 zk 集群的搭建步骤,可参考 ZooKeeper的安装与部署

在 zk 官网下载最新版本的 zk 二进制安装包,解压,将 conf 目录下 zoo_sample.cfg 文件复制为 zoo.cfg,然后在 zk 主目录执行命令,将 zk 启动起来。此时 zk 会监听默认的 2181 端口。

1
bin/zkServer.sh start

下载源代码

本文的 Dubbo 入门应用程序很简单,服务端接收到客户端请求,然后直接将消息返回给客户端。应用程序可以通过 XML、注解和 API 三种方式编写。

本文示例应用程序在 https://github.com/zonghaishang/dubbo-samples 可以下载。

下载后,使用 IDEA 打开,导入 pom.xml 所需的依赖后显示如下:

阅读全文 »