Mkless

Mkless 查看完整档案

北京编辑  |  填写毕业院校  |  填写所在公司/组织 www.wjk123.com 编辑
编辑

设计模式、架构设计、编程思想、数据结构

个人动态

Mkless 收藏了文章 · 2月20日

docker-compose 详细指令

默认的模版文件名

docker-compose.yml

version: '3'

services:
    webapp:
        image: examples/web
        ports:
            - '80:80'
        volumes:
            - '/data'

build

指定Dockerfile所在文件夹的路径, Compose将会利用它自动构建这个镜像,然后使用这个镜像
context     指定Dockerfile所在文件夹的路径
dockerfile  指定Dockerfile文件名
arg         指定构建镜像时的变量
cache_from  指定构建镜像的缓存

version: '3'
services:

    webapp:
        build:
            context: ./dir
            cache_from:
                - alpine:latest
                - corp/web_app:3.14
            dockerfile: Dockerfile-alternate
            args:
                buildno: 1

cap_add, cap_drop

指定容器的内核能力(capacity)分配

cap_add:
    - ALL #用于所有能力

cap_drop:
    - NET_ADMIN #去掉NET_ADMIN能力

command

覆盖容器启动后默认执行的命令

command: echo 'hello world'

configs

仅用于Swarm mode

cgroup_parent

指定父cgroup组 继承改组的资源限制

cgroup_parent: cgroups_1  #创建了一个cgroup组名称为cgroups_1

container_name

指定容器名称 默认使用 项目名称_服务名称_序号 

container_name: docker-web-container # 指定名称后无法使用扩展(scale)

deploy

仅用于Swarm mode

devices

指定设备映射关系

devices:
    - "/dev/ttyUSB1:/dev/ttyUSB0"

depends_on

解决容器的依赖、启动先后的问题(下例中先启动redis db 再启动web)

version: '3'

services:
    web:
        build: .
        depends_on:
            - db
            - redis
    redis:
        image: redis
    
    db:
        image: postgres

注意: web服务不会等待redis db 完全启动之后才启动        

dns

自定义DNS服务器。

dns: 8.8.8.8

dns:
    - 8.8.8.8
    - 114.114.114.114

dns_search

配置DNS搜索域

dns_search: examples.com

dns_search:
    - domain1.example.com
    - domain2.example.com

tmpfs

挂载一个tmpfs文件系统到容器

tmpfs: /run
tmpfs:
    - /run
    - /tmp

env_file

从文件中获取环境变量,可以为单独的文件路径或列表

env_file: .env

env_file:
    - ./common.env
    - ./apps/web.env
    - /opt/secrets.env
    
环境变量文件每一行必须符合格式,支持 # 开头的注释行

# common.env: Set development environment
PROG_ENV=development

environment

设置环境变量 可以使用数组和字典两种格式

environment:
    PACK_ENV: development
    SESSION_SECRET:
    
environment:
    - RACK_ENV=development
    - SESSION_SECRET

expose

暴露端口,但不映射到宿主机,只被连接的服务访问。

expose:
    - "3000"
    - "8000"

external_links[不建议使用]

链接到外部容器,甚至到非Compose管理的外部容器

extra_hosts

类似Docker中的 --add-host,指定额外的host名称映射信息
extra_hosts:
    - "googledns:8.8.8.8"
    - "dockerhub:52.1.157.61"
    
会在启动后的服务容器中/etc/hosts文件中添加如下两条

8.8.8.8 googledns
52.1.157.61 dockerhub

healthcheck

检查容器是否健康运行

healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost"]
    interval: 1m30s
    tomeout: 10s
    retries: 3

image

指定为镜像名称或镜像ID,不存在则会去拉取

image: ubuntu
image: orchardup/postgresql
image: a4bc65fd

labels

为容器添加Docker元数据(metadata)信息

labels:
    com.startupteam.description: "webapp for a startup team"
    com.startupteam.department: "devops department"
    com.startupteam.release: "rc3 for v1.0"

links [不推荐使用]

logging

配置日志选项
logging:
    driver: syslog
    options:
        syslog-address: "tcp://192.168.0.42:123"
        
目前支持三种日志驱动类型
driver: "json-file"
driver: "syslog"
driver: "none"

options配置日志驱动的相关参数
options:
    max-size: "200k"
    max-file: "10"

network_mode

设置网络模式。使用和docker run 的 --network参数一样的值

network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

networks

配置容器连接的网络

version: '3'
services:
    
    some-service:
        networks:
            - some-network
            - other-network
            
networks:
    some-network:
    other-network:

pid

跟主机系统共享进程命名空间。容器之间可以通过进程ID来相互访问和操作。

pid: "host"

ports

暴露端口信息。使用宿主端口:容器端口格式,或者仅仅指定容器端口(宿主机将随机端口)

ports:
    - "3000"
    - "8000:8000"
    - "49100:22"
    - "127.0.0.1:8001:8001"

secrets

存储敏感数据,例如mysql服务密码

version: "3"
services:

mysql:
    image:mysql
    environment:
        MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
    secrets:
        - db_root_password
        - my_other_secret
        
secrets:
    my_secret:
        file: ./my_secret.txt
    my_other_secret:
        external:true

security_opt

指定容器模版标签(label)机制的默认属性(用户,角色,类型, 级别)

security_opt:
    - label:user:USER
    - label:role:ROLE

stop_signal

设置另一个信号来停止容器

stop_signal: SIGUSER1

sysctls

配置容器内核参数

sysctls:
    net.core.somaxconn: 1024
    net.ipv4.tcp_syncookies: 0
    
sysctls:
    - net.core.somaxconn=1024
    - net.ipv4.tcp_syncookies=0

指定容器的ulimits限制值

ulimits:
    nproc: 65535
    nofile:
        soft:20000
        hard:40000

volumes

数据卷所挂载路径设置,可以设置宿主机路径或加上访问模式,支持相对路径

volumes:
    - /var/lib/mysql
    - cache/:/tmp/cache
    - ~/configs:/etc/configs/:ro

其他指令

entrypoint: /code/entrypoint.sh   # 指定服务容器启动后执行的入口文件
user: nginx                       # 指定容器中运行应用的用户名
working_dir: /code                # 指定容器中的工作目录
domainname: your_website.com      # 指定容器中搜索域名
hostname: test                    # 主机名
mac_address: 08-00-27-00-0C-0A    # MAC地址
privileged: true                  # 允许容器中运行一些特权命令
restart: always                   # 指定容器退出后的重启策略为始终重启
read_only: true                   # 以只读模式挂载容器的root文件系统,意味着不能对容器内容修改
stdin_open: true                  # 打开标准输入,可以接受外部输入
tty: true                         # 模拟一个伪终端

读取变量

Compose模版文件支持动态读取主机的系统环境变量和当前目录下.env文件中的变量
eg: 从运行它的环境变量中读取变量${MONGO_VERSION}的值,并写入执行的指令中。
version: '3'
services:

db:
    image: "mongo:${MONGO_VERSION}" 
    
当前目录若存在.env文件,执行docker-compose则将从该文件中读取变量

# 支持 # 号注释
MONGO_VERSION=3.6
查看原文

Mkless 收藏了文章 · 2020-12-25

FPT+lsyncd实现多服务器文件分发(文件同步)

[TOC]

一.应用场景

简介:当程序应用通过FTP上传文件到文件服务器后,文件服务器会将新上传的文件同步分发到已配置好的服务器。

应用场景:

  1. 大流量视频网站中,为了保证视频能够流畅播放,需要做推流服务器的集群,这些集群需要保证视频文件的一致性,所以需要服务器之间的文件分发同步。
  2. 有文件同步需求的服务器集群应用。

结构流程图如下:

文件同步-1584412940700.jpg

二.服务器配置

本教程使用Windows10+VMware Workstation Pro,用虚拟机来做演示。用到的Linux发行版,均为CentOS7。

简单起见,只配置了一台文件分发主机,两台从机。安装虚拟机略过。

虚拟机均采用网络桥接的方式,分配了内网的IP,后面操作均通过xshell软件,远程操作。

主机Linux发行版IP地址
文件服务器 ftp和lsyncd的serverCentOS710.10.67.139
客户机1 rsync clientCentOS710.10.67.141
客户机2 rsync clientCentOS710.10.67.149

三.搭建ftp服务器

安装前,可以一下配置阿里云yum源,提高yum下载速度。

curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum makecache

CentOS7搭建ftp服务器,简单总结有如下几个步骤:

  • 第一步,通过yum安装vsftpd;
  • 第二步,正确配置vsftpd;
  • 第三步,新增ftp用户,并配置其访问路径;
  • 第四步,防火墙和SELinux的配置;
  • 第五步,可能会遇到的一些问题;

1.安装vsftpd

yum install -y vsftpd

2.修改配置文件

vsftpd有多种配置方式,本文使用一种比较简单通用的配置。

关于vsftpd的各种配置方式,请参考:https://blog.51cto.com/meilin...


打开配置文件(如果不熟悉Linux系统,建议将配置文件弄到Windows用户VSCode等文本编辑工具编辑)

vi /etc/vsftpd/vsftpd.conf

修改配置文件如下:

1.不允许匿名访问

anonymous_enable=NO

2.允许使用本地帐户进行FTP用户登录验证

local_enable=YES

3.使用户不能离开主目录

当chroot_list_enable=YES,chroot_local_user=YES时,在/etc/vsftpd.chroot_list文件中列出的用户,可以切换到其他目录;未在文件中列出的用户,不能切换到其他目录。

chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list

配置文件最后添加(不添加会启动失败)

500 OOPS: vsftpd: refusing to run with writable root inside chroot()

如果/etc/vsftpd/chroot_list不存在,则需要创建该文件:

vi /etc/vsftpd/chroot_list

:wq直接保存并退出就行。(创建一个空文件即可)

4.设定支持ASCII模式的上传和下载功能。

ascii_upload_enable=YES
ascii_download_enable=YES 

5.修改完配置文件后,启动vsftpd服务

systemctl start vsftpd.service # 启动命令
systemctl status -l vsftpd.service # 查看启动状态

6.配置文件参考

anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
ascii_upload_enable=YES
ascii_download_enable=YES
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
listen=NO
listen_ipv6=YES

pam_service_name=vsftpd
userlist_enable=YES
tcp_wrappers=YES
allow_writeable_chroot=YES

<u>备注:如果嫌配置麻烦,想直接替换配置文件的话,请留意第3点,记得要创建/etc/vsftpd/chroot_list。</u>

3.创建ftp用户

1.创建用户

useradd -d /var/www/vod -g ftp -s /sbin/nologin ftpuser

注意:/var/ftp/public_root是ftp的访问路径,ftpuser是ftp用户。可以根据自己的情况修改。

2.修改该FTP用户密码

passwd ftpuser  

3.确保该用户创建成功

cat /etc/passwd #查看ftpusr是否新建成功,以及路径是否正确

4.使用FTP工具登录测试

这里使用FileZilla Client登录FTP。

image-20200317142707237.png

5.防火墙和SELinux的配置

到上一步,通过工具连接FTP,会遇到一些问题,这些问题一般是由于防火墙和SELinux的配置导致的。

详细的说明和处理方法,参考:https://blog.csdn.net/LeoFitz...

关于防火墙,需要开放21和22端口,这里为了方便起见,直接关掉防火墙。

#执行关闭命令: 
systemctl stop firewalld.service
#再次执行查看防火墙命令:
systemctl status firewalld.service
#执行开机禁用防火墙自启命令  :
systemctl disable firewalld.service

SELinux的配置:

setsebool -P tftp_home_dir 1
setsebool -P allow_ftpd_full_access 1

四.主服务器server端安装lsyncd并配置

1.yum 安装 lsyncd

[root@user ~]# yum -y install lsyncd #安装
[root@user ~]# rpm -qa lsyncd #查看安装是否成功
lsyncd-2.2.2-1.el7.x86_64
[root@user ~]# rpm -qc lsyncd  #查看lsyncd的文件路径
/etc/logrotate.d/lsyncd
/etc/lsyncd.conf   #==》Lsyncd主配置文件
/etc/sysconfig/lsyncd

2.配置lsyncd

安装好 lsyncd 后,找到其配置文件:/etc/lsyncd.conf。

lsyncd 中,远程服务器的文件同步有两种实现:1.rsync 2.ssh

使用 rsync,需要在 client 端配置 rsync。使用 ssh,需要 service 端可以通过 ssh 免密登录 client 端。

推荐使用rsync方式,速度快,更可靠

lsyncd的配置文件分为两部分:

1、settings 部分 关于lsyncd工具自身的一些选项设置

2、sync 部分 主要用来定义同步时的一些设置,可以同时同步多个目录,只需要在该代码块中事先定义好多个sync即可

具体的配置和其他使用方法,可以参考:


这里给出本示例的配置文件:

settings {
    logfile      = "/var/log/lsyncd/lsyncd.log",
    statusFile   = "/var/log/lsyncd/lsyncd.status",
    inotifyMode  = "CloseWrite",
    insist       = true
}

sync {
    default.rsync,
    source    = "/var/www/vod",  
    target    = "rsyncuser@10.10.67.141::backup",
    delay     = 0,
    rsync     = {
        binary    = "/usr/bin/rsync",
        password_file = "/etc/images.pas",
        archive   = true,
        compress = false,
        verbose   = true
        }
}

sync {
    default.rsync,
    source    = "/var/www/vod",  
    target    = "rsyncuser@10.10.67.149::backup",
    delay     = 0,
    rsync     = {
        binary    = "/usr/bin/rsync",
        password_file = "/etc/images.pas",
        archive   = true,
        compress = false,
        verbose   = true
        }
}

说明:

一个sync{ }配置就对应一个client端。

其中,核心就是 :

target = "rsyncuser@10.10.67.149::backup" ,rsyncuser和::后面的模块名称,需要在client端配置rsync,中间的IP地址大家都应该懂。

source = "/var/www/vod",主服务器分发文件的根路径。

第二点,因为client端的rsync是需要配置用户名和密码的,用户名在上面已经提到了,密码需要另外创建一个密码文件。

配置里面是这样写的: password_file = "/etc/images.pas"

所以要在这个路径下新建这个密码文件,server端需要配置一个密码文件,与client端对应。

vim /etc/images.pas # 创建密码文件

里面的内容,直接填写你想要密码就可以了。这里我使用 123456

所以这个文件的内容就是123456 , 不要写其他任何内容,前面也不要有空格。

注意: rsync也需要一个密码文件,但是格式不同,后面会提到。


3.启动服务

配置文件写好之后,启动服务

#启动服务:
sudo systemctl start lsyncd
#查看启动日志:
sudo systemctl status -l lsyncd

注意:如果client端没有配置好rsync,直接启动lsyncd会失败。但是,如果在配置文件中的setting中配置了 insist=true,则会直接启动lsyncd,一直检测client的连接情况,可以连接成功的,就同步文件

五.从服务器client端安装rsync并配置

1.安装并编辑配置文件

yum -y install rsync # 安装
vim /etc/rsyncd.conf # 配置

2.配置文件内容

uid = root
gid = root
use chroot = yes
max connections=0
log file=/var/log/rsyncd/rsyncd.log
pid file=/var/run/rsyncd.pid
lock file=/var/run/rsyncd.lock

[backup]
path = /var/www/vod
read only = no
list = yes
auth users = rsyncuser
secrets file = /etc/images.pas

说明:

1.[backup] 为模块名称,与上文中在lsyncd中配置的“target = "rsyncuser@10.10.67.149::backup"”对应

2.auth users = rsyncuser,同上

3.path表示,希望将文件同步到哪个路径

3.上文提到的密码文件,与这个配置对应 secrets file = /etc/images.pas

创建client端的密码文件(注意内容的格式!这个密码文件格式为: 用户名:密码):

vim /etc/images.pas # 创建密码文件
# 文件内容(与配置文件中auth users对应):
# rsyncuser:123456
chmod 600 /etc/images.pas # 修改密码文件权限

3.启动rsync

/usr/bin/rsync --port=873 --daemon # 启动
ps -ef|grep rsync # 查看进程是否启动成功

六.使用示例

步骤:

  1. 应用程序或者工具,通过ftp上传文件到指定的文件夹。本示例的文件夹路径为:/var/www/vod
  2. lsyncd检测到/var/www/vod路径下有文件变动,开始执行文件同步。
  3. 根据配置,新增的文件,将会通过rsync同步到从服务器client的指定路径。本示例的路径为:/var/www/vod。

主服务器server端的配置文件

image-20200317152812948.png

从服务器client端的配置文件

image-20200317155631371.png

启动client的rsync服务:

image-20200317154751196.png

启动server的lsyncd服务:

image-20200317154834883.png

使用ftp上传文件

使用FileZilla Client工具

image-20200317155952281.png

上传了两个文件file01.zip file02.zip

查看是否同步成功

client1同步成功

image-20200317160041561.png

client2同步成功
image-20200317160101705.png

查看原文

Mkless 关注了专栏 · 2020-12-21

美团技术团队

“美团技术团队”,你最值得关注的技术团队官方微信公众号。 每周会推送来自一线的实践技术文章,涵盖前端(Web、iOS和Android)、后台、大数据、AI/算法、测试、运维等技术领域。 在这里,与8000多业界一流工程师交流切磋。

关注 12108

Mkless 赞了回答 · 2020-12-21

解决python3循环导入报错

不能这么导入
import os 导入的os类型是<class 'module'>
import i 导入的这个变量i的类型是<class 'str'>

关注 2 回答 2

Mkless 赞了文章 · 2020-12-20

2021年最热门的5种编程语言

介绍

截至2020年,大约有700种编程语言可用[1]。其中一些倾向于仅适用于特定领域,而其他一些则因其能够在各种应用中工作的能力而广受赞赏。在过去的十年中,软件的应用几乎稳定增长,并且为了满足需求而开发了新的语言。在本文中,我们将探讨数据科学和云开发领域中一些最常用的编程语言和潜在的新星。

决定在业余时间学习一种相对较新的编程语言有时可能是对我们时间的冒险投资,因为我们不确定未来几年就业市场将如何看待这种新语言。另一方面,在大多数情况下,较新的编程语言都经过精心设计,以充分利用最新的技术进步,因此从长远来看有可能为我们提供优势。因此,使用更新的编程语言的一些主要优点可能是:

· 硬件优化(GPU,多核CPU系统)。
· 改进的网络。
· 更简洁的代码。
· 键入推断。
· 更轻松的容器化和云支持。

根据2020年Stackoverflow开发人员调查[2],以下编程语言是2020年开发人员最喜欢的语言(图1)。作为本文的一部分,我们将考虑其中的5个。

图片

Figure 1: Most loved programming languages

此外,根据Stackoverflow开发人员调查,这是2020年排名前10位的付费编程语言(图2)。

图片

Figure 2: Languages associated with the highest salaries worldwide

编程语言

Julia

像Python和R这样的编程语言由于易于使用,现在在诸如数据科学,机器学习和通用计算/数字任务等领域非常流行。但是,这些语言最初并不是为在高度可扩展的系统上工作而设计的。因此,这对于大型企业解决方案而言,很难使用这种类型的编程语言。为了克服这种类型的问题,Julia是由麻省理工学院(MIT)的一组研究人员创建的。朱莉娅的一些关键特征是:

· 为与并行和分布式系统一起使用而优化。

· 内置包管理器。

· 支持C编程功能。

· 动态键入。

为了促进采用,已经实现了许多数据科学和机器学习库,例如ScikitLearn.jl,TextAnalysis.jl,StatsModels.jl。此外,Julia还可以在传统的Jupyter笔记本中使用。如果您有兴趣了解有关Julia的更多数据科学知识,那么此YouTube课程是一个很好的起点。

从图3可以看出,在过去的几年中,茱莉亚到目前为止Google搜索的整体数量在增加。

图片

Figure 3: Julia Google Trends [3]

Go

Go是当今最有前途的系统编程语言之一。实际上,这种编程语言是Google开发的,目的是简化应用程序和开发的规模。Go的一些关键特征是:

· 专为云原生开发而设计。实际上,主流工具(例如Docker和Kubernetes)已使用Go开发。

· 内存管理(与C和C ++等语言不同,它具有嵌入式的Garbage Collector)。

· 出色的并发支持。

在2014年左右达到顶峰后,Go多年来一直在Google搜索量中保持一致。Go是当前在Cloud平台(例如Google Cloud Platform和Microsoft Azure)上最受欢迎的编程语言之一。

图片

Figure 4: Go Google Trends [3]

如果您对使用Go语言编写机器学习算法感兴趣,那么GoLearn是一个很好的起点。

Python

如今,Python是用于数据科学和机器学习任务的最受欢迎的编程语言。它是由Guido van Rossum于1991年首先开发的,此后它的受欢迎程度才刚刚提高(图5)。

图片

Figure 5: Python Google Trends [3]

用于数据科学和机器学习的一些最受欢迎的Python库是:

· Pandas

· Numpy

· scikit学习

· TensorFlow

· Pytorch

如前所述,与Python相关的关键问题之一是它的可伸缩性性能不佳。为了尝试解决此问题,已实现了不同的系统(例如Cython和Numba),以在使用Python进行编码时创建类似C的性能级别。

Scala

目前,Scala被认为是函数式编程的最佳编程语言之一(尽管它仍然提供对面向对象编程方法的支持)。就搜索受欢迎程度而言,Scala似乎在2018–2019年间在Google搜索上达到顶峰(图6)。

图片

Figure 6: Scala Google Trends [3]

使用Scala的一些主要优点是:

· Scala是一种静态类型的语言。

· 与Python等编程语言相比,速度要快得多。

· 与Java的兼容性。

· 能够结合功能和面向对象的编程。

Scala受欢迎的主要原因之一是Apache Spark(使用Scala构建的数据管理工具)。实际上,Apache Spark是用于Hadoop集成(快速处理大量数据)的最受欢迎的大数据工具之一。

JavaScript

最后,JavaScript是目前最流行的网络编程语言之一,几乎可以在任何类型的应用程序(例如服务器,移动设备,云,微控制器等)上运行。

在网络开发的早期,Javascript的普及率达到了顶峰,此后在过去十年中一直保持稳定的趋势(图7)。

图片

Figure 7: Javascript Google Trends [3]

之所以将Javascript包含在此列表中,主要原因之一是它能够在网络上共享数据科学和机器学习项目。实际上,在过去的几年中,已经开发了不同的框架,例如TensorFlow.js,ONNX.js,Plotly.js,Dash等,以便在以Python等编程语言创建的Web项目上可访问。

结论

总体而言,Python和Javascript无疑是目前最受欢迎的两种编程语言。尽管,如本文所示,Julia,Go和Scala等不同的替代产品由于其各种好处(现在的方式可能与过去十年中的Python相同)现在开始在就业市场上获得越来越多的关注。

(本文由闻数起舞翻译自follow me on Medium的文章《Top 5 Programming Languages to bet on for 2021》,转载请注明出处,原文链接:https://towardsdatascience.co...

image

查看原文

赞 4 收藏 1 评论 0

Mkless 关注了标签 · 2020-12-19

milvus

milvus 向量搜索引擎

关注 0

Mkless 关注了标签 · 2020-12-13

python

Python(发音:英[ˈpaɪθən],美[ˈpaɪθɑ:n]),是一种面向对象、直译式电脑编程语言,也是一种功能强大的通用型语言,已经具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法非常简捷和清晰,与其它大多数程序设计语言不一样,它使用缩进来定义语句。

Python支持命令式程序设计、面向对象程序设计、函数式编程、面向切面编程、泛型编程多种编程范式。与Scheme、Ruby、Perl、Tcl等动态语言一样,Python具备垃圾回收功能,能够自动管理存储器使用。它经常被当作脚本语言用于处理系统管理任务和网络程序编写,然而它也非常适合完成各种高级任务。Python虚拟机本身几乎可以在所有的作业系统中运行。使用一些诸如py2exe、PyPy、PyInstaller之类的工具可以将Python源代码转换成可以脱离Python解释器运行的程序。

Python的主要参考实现是CPython,它是一个由社区驱动的自由软件。目前由Python软件基金会管理。基于这种语言的相关技术正在飞快的发展,用户数量快速扩大,相关的资源非常多。

关注 134756

Mkless 收藏了文章 · 2020-11-30

【PHP 扩展开发】Zephir 简介

什么是 Zephir

Zephir 是一种中间语言,以接近 PHP 的语法来编写代码,然后转换编译成 PHP 扩展,旨在简化 PHP 扩展的创建和可维护性。利用编译来提高性能和资源消耗,又不需要关注内存管理等复杂操作。

安装

要使用 Zephir 开发 PHP 扩展 ,需要满足以下要求 (以 centos7 + php7.2 为例)

编译环境

官方示例以 ubuntu ,需要安装如下扩展

sudo apt-get install git gcc make re2c php php-json php-dev libpcre3-dev build-essential

我们用 centos ,yum 安装

yum install -y git gcc make re2c autoconf automake libtool pcre pcre-devel

yum groupinstall -y "Development Tools"

某些库可能某些源没有,可以更换源或者下载源码安装

php 扩展

Zephir parser >= 1.1.0

wget https://github.com/phalcon/php-zephir-parser/archive/v1.2.0.tar.gz

mv v1.2.0.tar.gz php-zephir-parser-v1.2.0.tar.gz

tar -xvzf php-zephir-parser-v1.2.0.tar.gz

cd php-zephir-parser-1.2.0/

/usr/local/php7/bin/phpize

./configure --with-php-config=/usr/local/php7/bin/php-config

make && make install

gmp (PHP 源码中包含该扩展,默认情况下不安装)

扩展安装方法大同小异,不另说明

以源码编译的方式追加安装这两扩展,并配置ini文件

extension=gmp.so
extension=zephir_parser.so

安装 Zephir

Zephir 目前有两个大版本在维护 0.10.X和0.11.X。两个版本差别比较大,我们选择0.11.X,下载最新版本,使用 phar 包

cd /usr/local/bin

wget https://github.com/phalcon/zephir/releases/download/0.11.10/zephir.phar

chmod 755 zephir.phar

ln -s /usr/local/bin/zephir zephir.phar

检查是否安装成功

zephir help

安装成装显示如下图

clipboard.png

创建扩展

初始化一个应用

zephir init first

生成如下两个目录和一个文件

clipboard.png

编写代码

注意:在 Zephir 中, 每个文件都必须包含一个类 (并且只有一个类)。 每个类都必须有一个命名空间, 并且目录结构必须与所使用的类和命名空间的名称相匹配。

使用 phpstorm 作为 IDE,安装 Zephir 插件。

first\first\hello.zep

namespace First;

class Hello
{

    public static function world() {
        echo "Hello world!";
    }

    public static function zephir() {
        echo "Hello Zephir!";
    }

}

编译

zephir build

第一次执行,运气不好的话会失败。详细日志见 compile-errors.log 文件的内容。

如果 build 成功,会自动生成 first.so 文件到 extension 目录 ,你需要编辑 php.ini 填加扩展

clipboard.png

测试一下

<?php

echo First\Hello::world(), "\n";

就这样,你也会 PHP 扩展开发了

附1:Available commands:

    init                Initializes a Zephir extension
    builddev            Generates/Builds/Installs a Zephir extension in development mode
    api                 Generates a HTML API based on the classes exposed in the extension
    clean               Cleans any object files created by the extension
    generate            Generates C code from the Zephir code without compiling it
    build               Generates/Builds/Installs a Zephir extension
    stubs               Generates stubs that can be used in a PHP IDE
    help                Displays this help and exit
    fullclean           Cleans any object files created by the extension (including files generated by phpize)
    compile             Compile a Zephir extension
    install             Installs the extension in the extension directory (may require root password)
    version             Shows the Zephir version

附2:Windows 编译扩展的方法
https://blog.csdn.net/abc1035...

查看原文

Mkless 赞了回答 · 2020-11-02

c/c++ 为什么函数中定义变量不会出现像 struct 中因内存对齐而导致的空间浪费

非常有意思的问题,网上找到两个回答
第一个说函数本地变量也应该内存对齐:https://bytes.com/topic/c/ans...

第二个说本地变量对齐的代价是非常大的(在3.6.2的开头):https://www.cl.cam.ac.uk/tech...

我自己写了c语言程序

int main(void){
    struct A {
        int a;
        char b;
        int c;
    };
    struct A A1 = {4,5,6};
    int a = 1;
    char b = 2;
    int c = 3;
    return 0;
}

然后用gcc编译为汇编后的关键部分为

    movl    $4, -12(%rbp)
    movb    $5, -8(%rbp)
    movl    $6, -4(%rbp)
    movl    $1, -20(%rbp)
    movb    $2, -21(%rbp)
    movl    $3, -16(%rbp)
    movl    $0, %eax
    popq    %rbp

可以看到struct确实有内存对齐,但是内部变量之间就没有了。个人猜测函数内部变量如果能做到内存对齐那效率自然是最高的。但是这个的难度很大,因为函数内部的变量有可能不是连续的,而struct内部的东西天然就是连续的

关注 1 回答 1

Mkless 关注了问题 · 2020-11-02

opencv编译出错,急!

image.png

关注 2 回答 0

认证与成就

  • 获得 163 次点赞
  • 获得 77 枚徽章 获得 1 枚金徽章, 获得 25 枚银徽章, 获得 51 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

(゚∀゚ )
暂时没有

注册于 2016-04-25
个人主页被 2.2k 人浏览