codekissyoung

codekissyoung 查看完整档案

北京编辑中国地质大学(北京)  |  地质学 编辑深圳卡尔酷软件  |  php工程师 编辑 codekissyoung.com 编辑
编辑

coder

个人动态

codekissyoung 关注了用户 · 1月10日

junbaor @junbaor

广泛涉略,快速学习
QQ:1904661626

关注 25

codekissyoung 关注了用户 · 1月9日

Bohr @coding101

不学习,如何肩负全面建设社会主义现代化任务。

关注 2948

codekissyoung 赞了文章 · 1月9日

Dockerfile、Docker-Compose基本命令与介绍

一、Dockerfile基本命名

指令说明备注
FROM指定所创建镜像的基础镜像第一条指令必须为 FROM 指令。格式为 FROM <image>FROM <image>:<tag>
MAINTAINER指定维护者信息格式为 MAINTAINER <name>
RUNRUN 指令通常用于安装应用和软件包。在镜像中要执行的命令,格式为 RUN <command>RUN ["executable", "param1", "param2"]。前者默认将在 shell 终端中运行命令,即 /bin/bash -c ;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN [“/bin/bash”, “-c”,”echo hello”] 。每条RUN指令将在当前镜像的基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用换行。例如:RUN apt-get update \&& apt-get install -ylibsnappy-dev zliblg-dev libbz2-dev \&& rm -rf /var/cache/apt
CMD指定启动容器时默认执行的命令支持三种格式:1. CMD["executable","param1","param2"]使用 exec 执行,推荐方式;2. CMD command param1 param2/bin/bash 中执行,提供给需要交互的应用;3. CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;
LABEL指定生成镜像的元数据标签信息
EXPOSE声明镜像内服务所监听的端口指定容器要打开的端口
ENV指定环境变量格式为 ENV <key> <value> 。 指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。
ADD赋值指定的路径下的内容到容器中的路径下,可以为URL;如果为tar文件,会自动解压到路径下相当于 COPY,但是比 COPY 功能更强大
COPY赋值本地主机的路径下的内容到容器中的路径下;一般情况下推荐使用COPY而不是ADD复制本地主机的 (为 Dockerfile 所在目录的相对路径)到容器中的。用法同ADD,唯一的不同是不能指定远程文件 URLS。
VOLUME创建数据挂载点挂载目录,格式为VOLUME ["/data"]
USER指定运行容器时的用户名或UID
WORKDIR配置工作目录指定当前工作目录,相当于 cd
ARG指定镜像内使用的参数(例如版本号信息等)
ONBUILD配置当前所创建的镜像作为其他镜像的基础镜像时,所执行的创建操作的命令
STOPSIGNAL容器退出的信号
HEALTHCHECK如何进行健康检查
CMD、ENTRYPOINT容器启动时执行指令配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖,而CMD是可以被覆盖的。如果需要覆盖,则可以使用docker run --entrypoint选项。每个 Dockerfile 中只能有一个ENTRYPOINT,当指定多个时,只有最后一个生效。
RUN 有两种使用方式:
  • RUN
  • RUN "executable", "param1", "param2"

每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像,后续的RUN都在之前RUN提交后的镜像为基础,镜像是分层的,可以通过一个镜像的任何一个历史提交点来创建,类似源码的 版本控制 。

exec 方式会被解析为一个 JSON 数组,所以必须使用双引号而不是单引号。exec 方式不会调用一个命令 shell,所以也就不会继承相应的变量,如:

RUN [ "echo", "$HOME" ]

这种方式是不会达到输出 HOME 变量的,正确的方式应该是这样的

RUN [ "sh", "-c", "echo", "$HOME" ]

RUN产生的缓存在下一次构建的时候是不会失效的,会被重用,可以使用--no-cache选项,即docker build --no-cache,如此便不会缓存。
注意:apt-get updateapt-get install 被放在一个 RUN 指令中执行,这样能够保证每次安装的是最新的包。如果 apt-get install 在单独的 RUN 中执行,则会使用 apt-get update 创建的镜像层,而这一层可能是很久以前缓存的。

CMD有三种使用方式:
CMD  "executable","param1","param2"
CMD  "param1","param2"
CMD command param1 param2 (shell form)

CMD指定在 Dockerfile 中只能使用一次,如果有多个,则只有最后一个会生效。

CMD的目的是为了在启动容器时提供一个默认的命令执行选项。如果用户启动容器时指定了运行的命令,则会覆盖掉CMD指定的命令。

CMD会在启动容器的时候执行,build 时不执行,而RUN只是在构建镜像的时候执行,后续镜像构建完成之后,启动容器就与RUN无关了,这个初学者容易弄混这个概念,这里简单注解一下。

Docker学习笔记:Dockerfile

二、Dockerfile 基本结构

    一般的,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。’#’ 为 Dockerfile 中的注释。先看下面一个小例子:

# This my first nginx Dockerfile
# Version 1.0

# Base images 基础镜像
FROM centos

#MAINTAINER 维护者信息
MAINTAINER tianfeiyu 

#ENV 设置环境变量
ENV PATH /usr/local/nginx/sbin:$PATH

#ADD  文件放在当前目录下,拷过去会自动解压
ADD nginx-1.8.0.tar.gz /usr/local/  
ADD epel-release-latest-7.noarch.rpm /usr/local/  

#RUN 执行以下命令 
RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all
RUN useradd -s /sbin/nologin -M www

#WORKDIR 相当于cd
WORKDIR /usr/local/nginx-1.8.0 

RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install

RUN echo "daemon off;" >> /etc/nginx.conf

#EXPOSE 映射端口
EXPOSE 80

#CMD 运行以下命令
CMD ["nginx"]

三、构建镜像

3.1 编写Dockerfile文件

vim Dockerfile

FROM alpine:latest
MAINTAINER troy
CMD echo "Hello Workd!"

3.2 构建镜像

docker build -t hello_world .

3.3 运行镜像

docker run hello_world

clipboard.png

记:

1.表示当前用户使用的shell是/bin/bash,所谓的shell你可以理解为操作系统和人之间交互的平台。例如windows系统的桌面环境就是一个shell。
bin目录中基本上都是可执行的命令。

启动容器并启动bash(交互方式):

$docker run -i -t <image_name/continar_id> /bin/bash

2.保存对容器的修改(commit) 当你对某一个容器做了修改之后(通过在容器中运行某一个命令),可以把对容器的修改保存下来,这样下次可以从保存后的最新状态运行该容器。

$docker commit ID new_image_name 

当然如果在保存成新镜像的时候想添加新的 dockerfile命令,比如,启动进入新的目录。

docker commit -c "WORKDIR /usr/bin" 07c5f9ed32b0 test-images

当然你也可以在旧镜像的基础上写一个新的dockerfile,用dockerfile生成新的镜像。
Note:image相当于类,container相当于实例,不过可以动态给实例安装新软件,然后把这个container用commit命令固化成一个image。

Dockerfile文件的每条指令生成镜像的一层(注:一个镜像不能超过127层)。Dockerfile中的指令被一条条地执行。每一步都创建一个新的容器,在容器中执行指令并提交修改。当所有指令执行完毕后,返回最终的镜像id。

前台运行:
CMD 指令就是用于指定默认的容器主进程的启动命令的。提到 CMD 就不得不提容器中应用在前台执行和后台执行的问题。这是初学者常出现的一个混淆。
Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,用 upstart/systemd 去启动后台服务,容器内没有后台服务的概念。
一些初学者将 CMD 写为:

CMD service nginx start

然后发现容器执行后就立即退出了。甚至在容器内去使用 systemctl 命令结果却发现根本执行不了。这就是因为没有搞明白前台、后台的概念,没有区分容器和虚拟机的差异,依旧在以传统虚拟机的角度去理解容器。
对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。
而使用 service nginx start 命令,则是希望 upstart 来以后台守护进程形式启动 nginx 服务。而刚才说了 CMD service nginx start 会被理解为

CMD [ "sh", "-c", "service nginx start"],

因此主进程实际上是 sh。那么当 service nginx start 命令结束后,sh 也就结束了,sh 作为主进程退出了,自然就会令容器退出。
正确的做法是直接执行 nginx 可执行文件,并且要求以前台形式运行。比如:

CMD ["nginx", "-g", "daemon off;"]

ENTRYPOINT [ "/usr/sbin/nginx", "-g", "daemon off;" ]

为什么要这么做呢?因为Docker容器仅在它的1号进程(PID为1)运行时,会保持运行。如果1号进程退出了,Docker容器也就退出了。

Shell 和 Exec 格式

我们可用两种方式指定 RUN、CMD 和 ENTRYPOINT 要运行的命令:Shell 格式和 Exec 格式,二者在使用上有细微的区别。
Shell 格式

<instruction> <command>

例如:

RUN apt-get install python3  

CMD echo "Hello world"  

ENTRYPOINT echo "Hello world" 

当指令执行时,shell 格式底层会调用 /bin/sh -c <command> 。
例如下面的 Dockerfile 片段:

ENV name Cloud Man  

ENTRYPOINT echo "Hello, $name" 

执行 docker run <image> 将输出:

Hello, Cloud Man

注意环境变量 name 已经被值 Cloud Man 替换。

下面来看 Exec 格式。

Exec 格式

<instruction> ["executable", "param1", "param2", ...]

例如:

RUN ["apt-get", "install", "python3"]  

CMD ["/bin/echo", "Hello world"]  

ENTRYPOINT ["/bin/echo", "Hello world"]

当指令执行时,会直接调用 <command>,不会被 shell 解析。
例如下面的 Dockerfile 片段:

ENV name Cloud Man  

ENTRYPOINT ["/bin/echo", "Hello, $name"]

运行容器将输出:

Hello, $name 

注意环境变量“name”没有被替换。
如果希望使用环境变量,照如下修改

ENV name Cloud Man  

ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $name"] 

运行容器将输出:

Hello, Cloud Man

CMD 和 ENTRYPOINT 推荐使用 Exec 格式,因为指令可读性更强,更容易理解。RUN 则两种格式都可以。

四、Docker-Compose

    一句话:docker-compose 是用来做docker 的多容器控制,是一个用来把 docker 自动化的东西。有了 docker-compose 你可以把所有繁复的 docker 操作全都一条命令,自动化的完成。

4.1 常用命令

docker-compose up -d nginx                     构建建启动nignx容器

docker-compose exec nginx bash            登录到nginx容器中

docker-compose down                              删除所有nginx容器,镜像

docker-compose ps                                   显示所有容器

docker-compose restart nginx                   重新启动nginx容器

docker-compose run --no-deps --rm php-fpm php -v  在php-fpm中不启动关联容器,并容器执行php -v 执行完成后删除容器

docker-compose build nginx                     构建镜像 。        

docker-compose build --no-cache nginx   不带缓存的构建。

docker-compose logs  nginx                     查看nginx的日志 

docker-compose logs -f nginx                   查看nginx的实时日志



docker-compose config  -q                        验证(docker-compose.yml)文件配置,当配置正确时,不输出任何内容,当文件配置错误,输出错误信息。 

docker-compose events --json nginx       以json的形式输出nginx的docker日志

docker-compose pause nginx                 暂停nignx容器

docker-compose unpause nginx             恢复ningx容器

docker-compose rm nginx                       删除容器(删除前必须关闭容器)

docker-compose stop nginx                    停止nignx容器

docker-compose start nginx                    启动nignx容器

4.2 docker-compose.yml

depends_on

在使用 Compose 时,最大的好处就是少打启动命令,但是一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。
例如在没启动数据库容器的时候启动了应用容器,这时候应用容器会因为找不到数据库而退出,为了避免这种情况我们需要加入一个标签,就是 depends_on,这个标签解决了容器的依赖、启动先后的问题。
例如下面容器会先启动 redis 和 db 两个服务,最后才启动 web 服务:

version: '2'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

注意的是,默认情况下使用 docker-compose up web 这样的方式启动 web 服务时,也会启动 redis 和 db 两个服务,因为在配置文件中定义了依赖关系。

links

还记得上面的depends_on吧,那个标签解决的是启动顺序问题,这个标签解决的是容器连接问题,与Docker client的--link一样效果,会连接到其它服务中的容器。
格式如下:

links:
 - db
 - db:database
 - redis

使用的别名将会自动在服务容器中的/etc/hosts里创建。例如:

172.12.2.186  db
172.12.2.186  database
172.12.2.187  redis

相应的环境变量也将被创建。

volumes

挂载一个目录或者一个已存在的数据卷容器,可以直接使用 [HOST:CONTAINER] 这样的格式,或者使用 [HOST:CONTAINER:ro] 这样的格式,后者对于容器来说,数据卷是只读的,这样可以有效保护宿主机的文件系统。
Compose的数据卷指定路径可以是相对路径,使用 . 或者 .. 来指定相对目录。
数据卷的格式可以是下面多种形式:

volumes:
  // 只是指定一个路径,Docker 会自动在创建一个数据卷(这个路径是容器内部的)。
  - /var/lib/mysql

  // 使用绝对路径挂载数据卷
  - /opt/data:/var/lib/mysql

  // 以 Compose 配置文件为中心的相对路径作为数据卷挂载到容器。
  - ./cache:/tmp/cache

  // 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/)。
  - ~/configs:/etc/configs/:ro

  // 已经存在的命名的数据卷。
  - datavolume:/var/lib/mysql

如果你不使用宿主机的路径,你可以指定一个volume_driver。

volume_driver: mydriver

volumes_from

从其它容器或者服务挂载数据卷,可选的参数是 :ro或者 :rw,前者表示容器只读,后者表示容器对数据卷是可读可写的。默认情况下是可读可写的。

volumes_from:
  - service_name
  - service_name:ro
  - container:container_name
  - container:container_name:rw

参考文档:1. docker与dockerfile教程
2. Docker系列教程22-docker-compose.yml常用命令
3. Shell 和 Exec 格式

查看原文

赞 6 收藏 5 评论 0

codekissyoung 关注了专栏 · 1月1日

刻意练习

技术学习点滴记录

关注 314

codekissyoung 关注了专栏 · 2020-12-15

成长之路

围绕php, java相关程序设计与开发。

关注 27

codekissyoung 关注了专栏 · 2020-08-30

GO语言笔记

GO笔记

关注 8

codekissyoung 关注了专栏 · 2020-06-01

这里好像没有人的技术分享

干货总结分享

关注 10

codekissyoung 关注了用户 · 2020-02-29

宜信技术学院 @crediteasetech

宜信技术学院是宜信旗下的金融科技能力展示与输出平台。通过分享在金融科技领域的开源成果、研发实践促进金融科技生态圈企业创新升级。

关注 2372

codekissyoung 赞了文章 · 2020-02-10

使用Prometheus针对自己的服务器采集自定义的参数

用一个简单的例子来说明。

我用express和http搭了一个最简单的服务器,监听在8081端口上。

clipboard1,1

在metrics endpoint上,我会打印出这个服务器从启动至今,服务了多少次请求。这里我只是简单使用一个维护在memory中的计数器来模拟服务请求个数。每次metrics被请求,计数器加一。
localhost:8081/metrics测试一下:

clipboard2,2

打开Prometheus服务器的配置文件prometheus.yml:

clipboard3,3

添加一条作业,static_configs的target配置成我自己的服务器 localhost:8081.

localhost:9090访问Prometheus的web UI:

clipboard4,4

切换到图形界面,即可看到随时间推移,我的服务器响应了服务请求的趋势图。横轴为时间点,纵轴为Prometheus服务器从我的测试服务器每隔默认的15秒收集到的服务响应请求。

clipboard5,5

要获取更多Jerry的原创文章,请关注公众号"汪子熙":
公众号截图

查看原文

赞 2 收藏 0 评论 0

codekissyoung 关注了标签 · 2020-02-10

prometheus

一个开源的 Docker 容器监控工具,基于时间序列。

关注 52

codekissyoung 回答了问题 · 2019-11-19

有10亿个整数,怎么设计散列函数,让它们均匀分布?

(整数) mod (大于10亿的最小素数)

(整数) mod (大于10亿的最小素数) 作为数组下标,下标的个数是够了,对素数取模的话,理论上来说,不同整数 计算出 相同下标值 的 概率 会比较小。这样 10 亿个整数 可以看成是 均匀分布的吧 !

关注 4 回答 1

codekissyoung 赞了回答 · 2019-10-25

解决文件空洞apue

这是原文,翻译的锅?
clipboard.png

关注 2 回答 1

codekissyoung 提出了问题 · 2018-12-26

这段C#加密方式是什么意思,能翻译成PHP么?

public static string Encrypt(string Text, string sKey)
{
    DESCryptoServiceProvider dESCryptoServiceProvider = new DESCryptoServiceProvider();
    byte[] bytes = Encoding.Default.GetBytes(Text);
    dESCryptoServiceProvider.Key = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
    dESCryptoServiceProvider.IV = Encoding.ASCII.GetBytes(FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
    MemoryStream expr_5B = new MemoryStream();
    CryptoStream expr_68 = new CryptoStream(expr_5B, dESCryptoServiceProvider.CreateEncryptor(), CryptoStreamMode.Write);
    expr_68.Write(bytes, 0, bytes.Length);
    expr_68.FlushFinalBlock();
    StringBuilder stringBuilder = new StringBuilder();
    byte[] array = expr_5B.ToArray();
    for (int i = 0; i < array.Length; i++)
    {
        byte b = array[i];
        stringBuilder.AppendFormat("{0:X2}", b);
    }
    return stringBuilder.ToString();
}

问题出现的环境背景及自己尝试过哪些方法

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)

你期待的结果是什么?实际看到的错误信息又是什么?

关注 1 回答 0

codekissyoung 提出了问题 · 2018-12-01

Mac下开发linux c程序,VS Code如何配置才能提示Linux下的专有库(比如epoll)定义的变量?

  1. 我在Mac下使用vs code 写 Linux c程序,自动同步到我远程Linux服务器机器上编译测试运行。
  2. 因为要使用 <epoll.h> 库, 里面的各种常量定义,在vs code下是没有提示的,或者提示该常量未定义,很不爽,问下有木有方法让Vscode 在Mac下也能识别epoll库?

clipboard.png

关注 1 回答 0

codekissyoung 提出了问题 · 2018-12-01

Mac下开发linux c程序,VS Code如何配置才能提示Linux下的专有库(比如epoll)定义的变量?

  1. 我在Mac下使用vs code 写 Linux c程序,自动同步到我远程Linux服务器机器上编译测试运行。
  2. 因为要使用 <epoll.h> 库, 里面的各种常量定义,在vs code下是没有提示的,或者提示该常量未定义,很不爽,问下有木有方法让Vscode 在Mac下也能识别epoll库?

clipboard.png

关注 1 回答 0

codekissyoung 提出了问题 · 2018-11-30

Mac下开发linux c程序,VS Code如何配置才能提示Linux下的专有库(比如epoll)定义的变量?

  1. 我在Mac下使用vs code 写 Linux c程序,自动同步到我远程Linux服务器机器上编译测试运行。
  2. 因为要使用 <epoll.h> 库, 里面的各种常量定义,在vs code下是没有提示的,或者提示该常量未定义,很不爽,问下有木有方法让Vscode 在Mac下也能识别epoll库?

clipboard.png

关注 1 回答 0

codekissyoung 赞了文章 · 2018-11-23

对 SegmentFault 社区提问标准的一些解释

有心的用户应该发现最近 SegmentFault 问答的审核趋向严格,甚至一些已经正常展示的问题都会因质量问题提示作者修改。随着社区用户的增长,新进入用户的习惯正逐渐冲击着之前社区形成的默契,我们的问答质量出现了一定程度的下降。这对整个社区的运营提出了挑战,我们不希望发生劣币驱逐良币的状况,因此有必要在这个问题上达成新的共识。

应该说 SegmentFault 的提问一直都是有具体的标准的(https://segmentfault.com/faq#...),但是在具体理解的时候每个人都会产生偏差,为了尽量缩小这个偏差,我们约定如下几个提问的原则:

  1. 回答者优先
  2. 考虑后来者

回答者优先

当你理解了回答者优先的原则,就会自然而然地理解我们的运营规范,甚至你都不需要时刻记住这些规范,因为它们只是保证这一原则的最低要求。

什么是回答者优先?简而言之,就是你在提问的时候要优先考虑回答者能否清晰准确地知晓你要表达的意思,我们在审核的时候也是以这一条标准做为最优先的准则。提问者怎么判断呢?很简单,把自己置于回答者的位子上去审视一下你的问题,看看做为回答者的你是否可以通过这些表述知晓题意。

以这条原则为出发点,我们会对存在以下情况的问题说不:

  1. 问题表述过于简略,往往就一句话甚至一个标题的。(举例:标题是“如何实现一个淘宝一样的网站?”,内容是:“如题”)
  2. 问题中完全没有自己的观点,也就是传说中的伸手党。伸手党的存在主要有两大害处,第一,你没有说出已经尝试过哪些方法,没有尽量为回答者排除错误情况,会大大降低回答者的答题效率。第二,你的付出过少,无法达到回答者的心里预期,会大大影响回答者的答题积极性。用通俗的话说就是,你自己都不重视自己的事情,其他人又凭什么去帮你呢?
  3. 问题的排版过于混乱。从语法上讲,我们并不认为 Markdown 语法比你手上要写的任何编程语言语法更加复杂。而混乱的排版至少表明你并不重视这个问题,也不重视回答者的感受。很多人没有把代码用 Markdown 包裹起来,我们也视为排版混乱。
  4. 没有代码或者用图片代替了代码。这是一个最近比较突出的问题,代码胜千言,准确简短的描述配上必要的代码,比你说一大堆废话要好得多,我们已经看到了无数可爱的回答者在问题下方的评论中呼唤代码。与不贴代码相比,用代码截图来代替代码走入了另一个误区,让我们还是站在回答者的角度,当你面对上百行没头没尾的代码时,怎么去调试它们呢?你想让回答者浪费自己宝贵的时间,照着你们的图片一个字一个字的敲进去么?所以,当你要这么做的时候,想一想本章的标题“回答者优先”。在这里,还有一个比较特殊的情况,就是错误信息算不算代码,可不可以用截图代替?在这里,给出明确的答复:算。大部分的错误信息,包括浏览器的出错,c, java等预编译语言的运行时错误,都是一个简单的文本,你可以直接用鼠标选中复制,用 Markdown 的代码块语法包裹后附加到问题里。这样可以大大方便回答者定位错误。

考虑后来者

考虑后来者可以说是我们创建这个社区的一大目的,我们之所以让大家的问题可以公开讨论,就是为了降低在开发领域的信息不对称,让后来者少走弯路。为了做到这一点,我们提倡大家:

  1. 标题应该直接地表达问题的中心思想,如果你是因为运行时抛出某些错误而提问,你可以直接写“为什么JAVA运行时抛出xxxx异常?”。而不要写什么“一个关于JAVA的问题?”,请问做为一个后来者,我能从你的标题里获得什么重要的信息呢?如果这则问题被搜索引擎索引了,后来者遇到同类问题是怎么搜索的呢?大家想想你们搜问题,是不是喜欢把错误信息直接丢到搜索框里,那么怎样才算一个有用的问题就不言而喻了。
  2. 不要用图片代替代码,不要用图片代替代码,不要用图片代替代码!图片里的内容不能被任何搜索引擎检索到,你的问题会变成信息海洋里的垃圾沉没水底,这不是我们做为社区所提倡的。
  3. 用好标签。标签的作用在于更好地组织内容,这也是为了方便后来者。所以首先不要滥用,你的标签一定要跟问题相关。其次,标签不是用来描述问题的,不要自己创造一些描述性的语言做为标签。通常选择标签就选择这个问题所涉及到的技术就可以了,而且尽量至少使用一个大的语言标签,比如“php, java, c, javascript” 等等。

一些措施

俗话说“用霹雳手段,显菩萨心肠”,我们的菩萨心肠在上面已经告诉大家了。为了保证这些目的能够达到,我们将采取一系列措施。除了在审核时我们会严格按照标准来执行之外,我们还鼓励大家共同维护社区的秩序。大家可以通过评论来提醒一些违规的内容,或者使用举报和建议关闭功能。

我们针对把代码截图到图片里的行为,专门开发了自动扫描机器人,它会最大程度地去监控这一行为,一旦发现这一情况会提醒你修改问题。如果在一小时内没有修改的话,这个问题会被提交人工审核后处理。注意:机器人可能存在误判行为,如果你确定你的内容没有存在这种情况,请放心交给我们人工审核即可,我们会及时处理。

写在最后

当我们在6年前创立 SegmentFault 的时候,愿景是做一个高质量的中文技术问答社区。当然现在 SegmentFault 上承载的不止有问答的内容,但它依然是整个社区重要的组成部分。经常有人向我们抱怨国内技术社区的讨论氛围,思想浮躁,问题质量差,伸手党盛行等等。当我们体量比较小的时候,我们总是以提高素质还需要时间之类的理由来安慰自己或者他人。而当我们逐渐成长为国内技术问答领域一支重要力量之后,我们已经无法逃避肩上的责任,因此我们希望带领整个社区一起进步,共同打造一个属于我们自己的技术家园。

更多阅读

查看原文

赞 143 收藏 11 评论 54

codekissyoung 关注了专栏 · 2018-09-04

codingstudy

编程文章

关注 17

codekissyoung 赞了回答 · 2018-04-25

解决php是否适合做后台长驻程序

既然这个问题问的是php 是否适合 做后台常驻程序,我觉得还是应该给一个非常明确的答案,即 不适合

诚如其他答案中所说,php可以实现所有功能,内存问题也逐步变好,这是好事,但这并不是php适合做这件事的理由。要说可以实现功能,采用awk + nc也可以写一个常驻后台的web server且性能不一定比php差,但实际上绝不会有人采用这种geek的技术方案。

php不适合做这件事的理由有三:

  1. php的设计目的是方便的构建动态网页,并非后台服务,使用一种语言工具应当尽可能扬长避短,勉力而为之并不合适。
  2. php缺乏内建的线程和非阻塞机制,采用fork的非阻塞方案已经在好几年前被证明是低效的,并非现在最合适的技术方案
  3. php缺乏制作后台常驻程序的库、框架、成功案例,相比其他在这个领域发展了许多年的语言、或专门为制作后台程序而生的语言(如C、Java、Go等),php并不合适

不过,php就算不适合做后台常驻程序,也并不妨碍它在某些情况下使用,比如

  • 没什么性能压力、对稳定性也没什么特别要求时
  • 必须调用很多php写的库,不方便使用其他语言重写时
  • 开发同学只会写php,又找不到更好的人来实现这个项目时

总之,能不使用php做后台程序就别用,如果用了且未来还会上量,最好早做用其他语言重写的打算吧。

关注 8 回答 12

codekissyoung 关注了用户 · 2018-04-25

Laruence @laruence

新浪微博平台及大数据部总架构师,PHP官方开发组核心成员, Zend外聘顾问

关注 201