如何给Egg.js项目开启80端口访问

为什么要因某些特殊情况,项目cdn做了防盗链,然后本地开发也收到了限制,在cdn设置了一些本地ip的白名单,居然对端口支持不好,结果有时候可以访问cdn资源,有时候又不行,无奈,和运维、后端商量讲开发地址暂时改成80端口,以便正常开发Egg.js的项目改端口很简单啦。但是也有一些要注意的,本文面向MacOS,当然Linux系统应该同样适用。如何做这里有几个方案,供君参考:修改package.json跑哪个命令就在这个命令后面加–port=80,例如:“start”: “egg-scripts start –daemon –title=egg-server-51la-web-egg –workers=2 –port=80”,…dev同理。配置config.local.js如果没有这个文件自己创建一个,当然这个对应的是开发模式下使用。部分配置如下:‘use strict’;module.exports = app => { const exports = {}; exports.cluster = { listen: { port: 80, hostname: ‘127.0.0.1’, }, }; return exports;};Nginx大法比较麻烦,不过看了下官方文档,应该也是可以很好的支持的。有兴趣请阅读该节:部署Warning如果你不看这部分,很遗憾,你肯定跑不起来。你可能会遇到下面这些异常情况:ERROR 3810 nodejs.AppWorkerDiedError: [master] app_worker#1:3813 died (code: 0, signal: null, suicide: false, state: dead), current workers: []原因是Node.js的服务器端默认是无法使用1024以下的端口的。咋办呢?使用sudo哈哈哈。就是这样:sudo npm start或者sodu npm run dev。也有可能是:ERROR 3709 [app_worker] server got error: bind EADDRINUSE null:80, code: EADDRINUSE端口被占用了!node.js的server服务无法在ctrl+c后立刻终止。比如默认7001未能正常关闭,通过config.local.js文件修改的80端口也没有能够生效,每次启动服务都是启动了新的端口7002,此时:需要查出占用7001的端口的pid,将它终止。操作效果大致如下:P750TM:51la-web-egg whidy$ lsof -i:7001COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAMEnode 2982 whidy 25u IPv6 0x2f7a1da313a05e4d 0t0 TCP *:afs3-callback (LISTEN)P750TM:51la-web-egg whidy$ killkill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec … or kill -l [sigspec]P750TM:51la-web-egg whidy$ kill 2982P750TM:51la-web-egg whidy$ lsof -i:7001上面用到两个命令:lsof -i:[端口号],kill [进程的PID],最后重新查询7001就没有任何返回,说明Ok了,再次执行sudo npm run dev,那么就很好的使用80端口了。参考egg.js启动命令Node.js EACCES error when listening on most ports本文仅作为总结形式,未能重新完整的实践整个流程,如果有操作跳跃性或错误欢迎提出 ...

March 15, 2019 · 1 min · jiezi

【Linux系统编程】普通用户绑定(bind)特权端口

有些知识不常使用真的容易忘啊,即使没有忘记,知识提取速度也够下午茶的。背景最近在学Haskell,今天用Haskell的Network.Socket模块实现了一个简单的基于TCP的daytime服务程序。程序运行阶段报了以下的错误:Network.Socket.bind: permission denied (Permission denied)我的第一反应怀疑是不是本地有服务程序占用端口号13,然后用命令netstat -tunl | grep 13查看,端口号并没有占用,所以第一种可能性不成立。是不是这个模块有类似的bug呢?但并没有查到。不放心,用C语言写了同样功能的程序,然后运行也会出错:bind error: Permission denied那是不是端口的问题,隐隐约约记得好像是小于1024的端口号不是预留给用户的。然后换了一个>=1024的端口,果然运行成功了。至此,思路才走上正轨。实际上小于1024的端口是特权端口,普通用户是没有权限绑定的。那如果我就是要用端口13呢,怎么解决呢?解决方案1.使用root权限运行最简单的方式就是登录root帐号,或者使用su切换到root。如果本机有配置sudo,普通用户也可使用该命令运行服务程序。2.使用setcap给服务程序赋予能力上一种方式是使用具有特权的用户,而该种方式是给程序赋予绑定特权端口的能力。操作如下:使用setcap ‘CAP_NET_BIND_SERVICE=+ep’ /path/to/program赋予(raise)绑定特权端口的能力使用setcap ‘CAP_NET_BIND_SERVICE=-ep’ /path/to/program清除(lower)绑定特权端口的能力也可使用setcap -r /path/to/program清除(remove)该程序的所有能力setcap简单使用说明除了CAP_NET_BIND_SERVICE,还有好多能力,可以参考capabilities(7)=、-是运算符,除此之外还有+;e和p是标记,除此之外还有i。可参考cap_from_text(3) Textual Representation一节的说明。setcap命令对内核有要求,必须>=2.6.24。 请关注我的公众号哦。

February 25, 2019 · 1 min · jiezi

实现Golang和Erlang的连接(Port)

title: 实现Golang和Erlang的连接(Port)categories: Golang在Erlang中,有很多种方式去实现与其他语言的交互,常见的几种方式有使用TCP协议交互使用Port使用Erl_Interface方式去实现CNodeNIF后面几种难度都是有的,也使用了比较复杂的C/C++,而且比较容易出现问题。TCP的方式是通过网络协议,个人也不是很喜欢,那就剩下Port方式去连接Erlang服务器。Erlang的官方文档中对Port的介绍在Erlang中使用Port非常简单,实际上就是通过标准输入输出流与外部程序就行交互。现在我还是沿用官方文档中代码,仅做部分修改,实现Erlang与Golang的交互。%% complex1.erl-module(complex1).-export([start/1, stop/0, init/1]).-export([foo/1, bar/1]).start(ExtPrg) -> spawn(?MODULE, init, [ExtPrg]).stop() -> complex ! stop.foo(X) -> call_port({foo, X}).bar(Y) -> call_port({bar, Y}).call_port(Msg) -> complex ! {call, self(), Msg}, receive {complex, Result} -> Result end.init(ExtPrg) -> register(complex, self()), process_flag(trap_exit, true), %% 注意{packet, 2}代表的是用2个字节表示传输的 %% Port = open_port({spawn, ExtPrg}, [{packet, 2}]), %% 在这里不去处理这个数据头,不需要这个参数 Port = open_port({spawn, ExtPrg}, []), loop(Port).loop(Port) -> receive {call, Caller, Msg} -> Port ! {self(), {command, encode(Msg)}}, receive {Port, {data, Data}} -> Caller ! {complex, decode(Data)} end, loop(Port); stop -> Port ! {self(), close}, receive {Port, closed} -> exit(normal) end; {‘EXIT’, Port, Reason} -> exit(port_terminated) end.%% 进行编码,将数据转成2进制encode({foo, X}) -> <<1:8, X:8>>;encode({bar, Y}) -> <<2:8, Y:8>>].%% 这里有点特别,decode(Data) -> erlang:list_to_binary(Data).对于Golang,需要读取标准输入流的数据,这里我用bufio处理下(其实也没有太多必要,哈哈哈)。因为这里没有使用数据流的头部来记录数据的长度,所以默认将数据长度设置为2的byte数组。// port.gopackage mainimport ( “bufio” “os”)func main() { reader := bufio.NewReader(os.Stdin) writer := bufio.NewWriter(os.Stdout) for { buff := make([]byte, 2) _, err := reader.Read(buff) if err != nil { panic(err.Error()) } switch int(buff[0]) { case 1: buff[1] = byte(foo(int(buff[1]))) case 2: buff[1] = byte(bar(int(buff[1]))) } writer.Write(buff[1:2]) // 这里需要注意,要用Flush进行处理,否则erlang端收不到信息 writer.Flush() }}func foo(num int) int { return num + 1}func bar(num int) int { return 2 * num}使用步骤1 编译golanggo build port.go步骤2 运行Erlang虚拟机unix> erlErlang (BEAM) emulator version 4.9.1.2Eshell V4.9.1.2 (abort with ^G)1> c(complex1).{ok,complex1}步骤3 运行2> complex1:start(“extprg”).<0.34.0>3> complex1:foo(3).44> complex1:bar(5).105> complex1:stop().stop ...

December 24, 2018 · 1 min · jiezi