gRPC入坑记

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gRPC入坑记相关的知识,希望对你有一定的参考价值。

参考技术A

概要

由于gRPC主要是谷歌开发的,由于一些已知的原因,gRPC跑demo还是不那么顺利的。单独写这一篇,主要是gRPC安装过程中的坑太多了,记录下来让大家少走弯路。

主要的坑:

本文讲解gRPC demo的同时,会介绍如何解决这些坑。本文对应的Github地址:https://github.com/52fhy/grpc-sample 。该仓库存储了demo示例,以及部分系统编译好的二进制包,大家觉得有些步骤里耗时实在太长了,可以直接clone该仓库,复制二进制包到对应目录(仅限测试开发,生产环境还是老老实实自己编译吧)。

升级GCC

gRPC命令行工具编译需要使用 GCC4.8及以上版本。CentOS6系列的内置版本是GCC4.7。

如果你的系统GCC版本>=4.8,可以忽略本节。如果仅使用golang、java,请忽略本节。

如果需要升级gcc至4.8或更高版本,建议直接采用安装SCL源之后安装devtoolset-6(devtoolset-6目前gcc版本为6.3),因为devtoolset-4及之前的版本都已经结束支持,只能通过其他方法安装。

升级到gcc 6.3:

需要注意的是scl命令启用只是 临时 的,退出shell或重启就会恢复原系统gcc版本。如果要长期使用gcc 6.3的话:

这样退出shell重新打开就是新版的gcc了。其它版本同理。

升级到gcc 7.3:

已经停止支持的devtoolset4(gcc 5.2)及之前版本的安装方法,可能比较慢,大家感兴趣的话可以尝试。

编译gRPC命令行工具

gRPC分C、JAVA、GO、NodeJS版本,C版本包括C++, Python, Ruby, Objective-C, php, C#,这些语言都是基于C版本开发的,共用代码库一个代码库。

如果使用C版本的gRPC,最终要从源码里编译出下列工具:

这些工具作为插件供proto编译器使用。需要先下载 grpc/grpc github上的源码。

这里有2个坑:

1、grpc/grpc仓库比较大,鉴于国内访问的网速,建议使用国内镜像。码云(https://gitee.com)提供了同步更新的镜像地址:

这样下载速度提高了不少。

2、git submodule update这个命令实际就是在下载.gitmodules文件里定义的第三方依赖项到third_party目录,这个依赖项有很多,大家可以打开.gitmodules文件查看下详情。依赖的仓库都在github上,下载没几个小时是下载不下来的,就等着慢慢下载吧。

回头想想,我们花费了很多时间,结果只是为了得到grpc的proto编译插件。

PHP相关支持

PHP暂时不支持作为grpc的服务端。作为客户端是可以的,需要机器安装:

其中protoc和protobuf c扩展已经在 Protobuf 小试牛刀 介绍过了,这里不再赘述。上一小节里如果安装成功,那么grpc_php_plugin也是有了的。下面介绍如何安装PHP版的gRPC库。

安装grpc c扩展:

要求:GCC编译器需要4.8及以上版本。可以使用pecl安装:

也可以指定版本:

或者下载源码(http://pecl.php.net/package/grpc)安装:

grpc/grpc代码库里也有PHP扩展的C源码,在grpc/src/php/ext/grpc目录,进去也可以直接编译。

编译完成后在php.ini里添加,使用php --ri grpc可以查看信息。

安装完C扩展后,还需要使用composer安装grpc的库:

gRPC示例

编写gRPC proto

一共定义了三个文件:

其中 User 作为 Model定义,Response 用于 RPC统一返回定义,GreeterService 则是服务接口定义。

限于篇幅,proto文件详见 https://github.com/52fhy/grpc-sample 仓库的proto目录。

GreeterService.proto文件内容如下:

这里面定义了一个service,相当于定义了一个服务接口,我们把方法名、参数定义好了,后面需要去实现它。由于gRPC不支持PHP作为服务端,这里我们使用Golang作为服务端。

首先需要使用proto工具编译出golang的代码:

执行成功,会在 Pb_Go目录里生成Go代码:

如果需要生成PHP客户端的代码,则需要使用grpc php的命令行工具grpc_php_plugin,前面小结如果执行成功,这个工具已经有了。然后:

最终生成的文件:

注意:编译那里如果我们不加--grpc_out=../$out --plugin=protoc-gen-grpc=/usr/local/bin/grpc_php_plugin,生成的PHP类是没有GreeterClient的。这个文件是gRPC编译工具自动生成的,用于连接gRPC服务端。

go编写服务

我们用Golang写服务端。上面虽然生成了Golang的部分代码,但真正的服务还没有写呢。

main.go

首先我们新建个main.go,代码不多,我直接贴出来:

然后就可以编译了。

有个大坑:go build main.go的时候会先下载go.mod里定义的依赖(依赖比较多,详情查看:https://github.com/52fhy/grpc-sample/blob/master/go.mod),其中下面这条非常慢,仓库太大了,虽然重定向到github:

为了快速下载,我在码云上做了镜像,地址:gitee.com/52fhy/google-api-go-client 。改了之后下载快多了。

编译成功后,生成了二进制文件main。我们可以直接运行:

go test

为了测试我们写的服务是否正常,可以写测试用例:

test_client.go

运行:

运行有点慢,感觉依赖的库多了。

php客户端

使用gRPC PHP客户端,确保你已经安装了:

示例:

client_test.php

运行后输出:

常见问题

1、CentOS6使用 go mod获取第三方依赖包unknown revision xxx错误

解决:其实go mod调用链中会用到一些git指令,当git版本比较旧时,调用失败产生错误,并给出歧义的提示信息。方法就是升级git版本,CentOS6自带的git是1.7版本。升级完毕后,再尝试go mod。

快速升级方法:

centos6:

2、PHP报错:Fatal error: Class \'Google\\Protobuf\\Internal\\Message\' not found

解决:请安装PHP的protobuf c扩展。

3、PHP报错:Fatal error: Class \'\\Grpc\\BaseStub\' not found

解决:使用composer require grpc/grpc安装grpc。另外对应的grpc C扩展也要安装。

4、下载 github release包很慢怎么办?

解决:下载Mac版 Free Download Manager 下载工具可以解决Github 下载缓慢或失败问题。速度嗖嗖的。

参考

1、为CentOS 6、7升级gcc至4.8、4.9、5.2、6.3、7.3等高版本

http://www.vpser.net/manage/centos-6-upgrade-gcc.html

2、centos 6.x/7.x使用yum升级git版本 - 夜空

https://blog.slogra.com/post-721.html

3、Protobuf 小试牛刀 - 飞鸿影

https://www.cnblogs.com/52fhy/p/11106670.html

(本文完)

PostgreSQL数据库执行mapper.xml时遇到结果映射(resultMap)关联的嵌套 Select 查询,多个参数传参入坑记

目录

 

1.环境

2.mapper.xml 主查询,当前传参方式导致PostgreSQL数据库执行时,大写转小写

3.mapper.xml 主查询,保证传参时大写不改变

4.结果映射(resultMap)

5.关联的嵌套 Select 查询

6. 执行的SQL日志--主查询

7.执行的SQL日志-关联的嵌套 Select 查询


1.环境

PostgreSQL数据库、SpringBoot 2.2.5.RELEASE、mybatis-plus 3.31

2.mapper.xml 主查询,当前传参方式导致PostgreSQL数据库执行时,大写转小写

因为:当前${type}传参方式,被认为是普通的字符串。PostgreSQL数据库会自动把大写转换为小写执行

<select id="getUsers" resultMap="getUsersMap">
    select u.*,cast(${type} as varchar) as orderType
    from
    sys_user u
</select>

3.mapper.xml 主查询,保证传参时大写不改变

<select id="getUsers" resultMap="getUsersMap">
    select u.*,cast(#{type} as varchar) as orderType
    from
    sys_user u
</select>

4.结果映射(resultMap)

<resultMap id="getUsersMap" type="com.xxx.SysUser">
        <id column="id" property="id"/>
        <result column="user_name" property="userName"/>
        <result column="state" property="state"/>
        <!--一对多-->
        <collection property="orders" select="queryOrders" javaType="list"
                    ofType="com.xxx.SysOrder" column="{id = id,orderType=orderType}">
            <id column="id" property="id"/>
            <result column="userId" property="userId"/>
            <result column="order_no" property="orderNo"/>
            <result column="order_state" property="orderState"/>
			<result column="order_type" property="orderType"/>
            <result column="address" property="address"/>
        </collection>
    </resultMap>

5.关联的嵌套 Select 查询

<select id="queryOrders" resultType="com.xxx.SysOrder">
        SELECT o.* from sys_order o
		<where>
			<if test="id != null ">
                AND o.user_id = #{id}
            </if>
			<if test="orderType != null and orderType != '' ">
                AND o.order_type = #{orderType}
            </if>
		</where>
    </select>

6. 执行的SQL日志--主查询

SELECT
	u.*, CAST ('PAY' AS VARCHAR) AS orderType
FROM
	sys_user u

7.执行的SQL日志-关联的嵌套 Select 查询

SELECT
	o.*
FROM
	sys_order o
WHERE
	o.user_id = 1
AND o.order_type = 'PAY'

 

以上是关于gRPC入坑记的主要内容,如果未能解决你的问题,请参考以下文章

gRPC入坑记

gRPC入门指南 — 简单RPC

GRPC在网页前端的使用

分布式TensorFlow 采坑记

conda命令入坑记

PuppeteerSharp入坑记