基于以太坊私有链搭建一个分布式应用【3】0+

3,795 views / 2018.03.15 / 11:11 下午

搭建Dapp(分布式应用)

非常不情愿的安装npm,然后sudo npm install -g truffle

会出现一个很NB的动画安装过程,默默地欣赏…

71j.cn@ubuntu:~$ mkdir dapp

71j.cn@ubuntu:~$ cd dapp

truffle unbox webpack # 初始化一个带ui的truffle项目

/usr/bin/env: ‘node’: No such file or directory

sudo ln -s /usr/bin/nodejs /usr/bin/node

又报错:

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode

因为 node的版本太低

sudo npm install -g n

sudo n stable

再来truffle unbox webpack,成功后可以看下当前的目录结构:

-contracts //智能合约存放目录

-migrations //智能合约abi及部署信息存目录

-test //测试文件

-truffle.js //truffle默认配置

-truffle-config.js //Windows下默认配置文件名与truffle冲突,可使用该文件解决

修改webpack.config.js,添加如下代码制定运行的服务器ip,注意如果只监听localhost, 理论上无法通过IP:PORT的方式访问。

devServer: {

host: ‘10.120.113.245’,

port: 8080,

},

配置truffle.js到私链:

module.exports = {

// See <http://truffleframework.com/docs/advanced/configuration>

// to customize your Truffle configuration!

networks: {

development: {

host: “10.120.113.245”,

port: 8101,

network_id: “*”, // * Match any network id

gas:4712388, //Gas limit used for deploys. Default is web3.eth.getBlock(“pending”).gasLimit==4712388.

gasPrice:18000000000, //Gas price used for deploys. Default is 100000000000 (100 Shannon).

from: “0xf4182f0dc92313f8e106fc033641c3351703911f”//From address used during migrations. Defaults to the first available account provided by your Ethereum client.

// provider – web3 provider instance Truffle should use to talk to the Ethereum network.

//          – function that returns a web3 provider instance (see below.)

//          – if specified, host and port are ignored.

}

},

solc: {

optimizer: {

enabled: true,

runs: 200

}

},

};

 

truffle migrate # Build, compile, & deploy the dap

这个过程比较慢,耐心等待。

npm run dev

就可以通过浏览器http:// 10.120.113.245:8101访问了。

 

部署自己的合约程序

 

deploy//这都是要自己编写的,具体的看代码吧,点这里下载

├── app

│   ├── index.html

│   ├── javascripts

│   │   └── app.js

│   └── stylesheets

│       └── app.css

├── contracts

│   ├── Conference.sol

│   └── Migrations.sol//这个是truffle管理合约用的合约

└── test

└── conference.js

 

rm -rf dapp/app

rm -rf dapp/contracts

rm -rf dapp/test

然后把deploy中的文件都复制到dapp中,进入dapp:

71j.cn@ubuntu:~/dapp$ truffle migrate –reset

Using network ‘development’.

 

Running migration: 1_initial_migration.js

Replacing Migrations…

… 0x08a2db9ceda488eb534f4e0364dc21d569ad7a7d822c12f2007021ff67d8dc3b

Migrations: 0xec2264304e81fe2a3d5f3f316ecd627ea44c285d

Saving successful migration to network…

… 0xfa324a40aac5d0d89da7c05ddb5382bc2c56bd21e92a4f2b5b34325c526c7d5e

Saving artifacts…

Running migration: 2_deploy_contracts.js

Replacing Conference…

… 0x2c45e7be5c5a40770a99c4a59e1f09bdc69168c96d45be62e46c6ba053d77cda

Conference: 0x7d2c18809639c3a019e3b82c3ec39da526a8beb2

Saving successful migration to network…

… 0x37fe62d2822977d15a2261c28f599df0418e567b0a0ed38870e4d556d5f12d4c

Saving artifacts…

 

然后看看我们的测试用例编写的怎样?

appadmin@ubuntu:~/dapp$ truffle test

Using network ‘development’.

 

[ ‘0xf4182f0dc92313f8e106fc033641c3351703911f’,

‘0x899a969874bec249e4ef439c75adb0c358913b95’,

‘0x6797c39109ec4676d3b5dbb4dc76f1143a0f633a’ ]

 

 

Contract: Conference

✓ Initial conference settings should match (2068ms)

✓ Should update quota (3570ms)

1) Should let you buy a ticket

 

Events emitted during test:

—————————

 

Deposit(_from: 0x899a969874bec249e4ef439c75adb0c358913b95, _amount: 1000000000000000000)

 

—————————

✓ Should issue a refund by owner only (10310ms)

 

 

3 passing (20s)

1 failing

 

1) Contract: Conference Should let you buy a ticket:

AssertionError: Difference should be what was sent: expected 11001296558000000000 to equal ‘1000000000000000000’

at test/conference.js:63:11

at <anonymous>

at process._tickCallback (internal/process/next_tick.js:118:7)

 

为什么有一个没通过?因为那哥们在挖矿呢…,把挖矿的改成account[3]就好了。

npm run dev

通过浏览器访问http:// 10.120.113.245:8101即可。

Categories: 感悟 Tags:

基于以太坊私有链搭建一个分布式应用【2】0+

5,526 views / 2018.03.15 / 10:10 下午

 

合约编写

 

合约编辑器有很多,我们用这个IDE http://remix.ethereum.org/

合约格式是sol,需要编译成js文件让geth执行。以上工具可以方便的实现。

Conference.sol示例:

pragma solidity ^0.4.19;

 

contract Conference {  // can be killed, so the owner gets sent the money in the end

 

address public organizer;

mapping (address => uint) public registrantsPaid;

uint public numRegistrants;

uint256 public ticketPrice;

uint public quota;

 

event Deposit(address _from, uint _amount); // so you can log the event,more information to see http://71j.cn

event Refund(address _to, uint _amount); // so you can log the event,more information to see http://71j.cn

 

function Conference() public{

organizer = msg.sender;

quota = 100;

ticketPrice = 1 ether;

numRegistrants = 0;

}

/** 1 msg 指谁调用该智能合约发来的信息。 注意:智能合约也是一个账户

* 2 msg 包含的成员:

* msg.data(bytes): 获取调用者传入的数据信息

* msg.gas(uint): 剩余的以太币

* msg.sender(address): 当前调用者的以太坊账户地址

* msg.sig(bytes4): first four bytes of cakkData

* msg.value(uint): number of wei sent with the message;注意: 只有当有以太坊币的转义时, 该变量才有值(除调用合约所花费以太币这种情况)

*/

function buyTicket(uint ticketNumber) payable public {

require(ticketNumber>0);

require(numRegistrants+ticketNumber <= quota);

uint totalPrice = ticketNumber*ticketPrice;

require(msg.value==totalPrice);

registrantsPaid[msg.sender] += totalPrice;

numRegistrants+=ticketNumber;

//this.transfer(totalPrice);

organizer.transfer(totalPrice);

Deposit(msg.sender, totalPrice);

}

/*Contracts that receive Ether directly (without a function call, i.e. using send or transfer) but do not define a fallback function throw an exception, sending back the Ether (this was different before Solidity v0.4.0). So if you want your contract to receive Ether, you have to implement a fallback function.

*/

function () public payable {

/*只要有支付行为,就会调用这个后备

函数。举例:

*合约计划仅接受用户转入指定价值的eth,如果用户转入eth较少,则直接返回异常,当用户转入eth较多,则将用户多转入的eth退回。

*在这里我们可以借助 fallback function,也就是后备函数进行转入金额的限定。

*/

 

}

 

function changeQuota(uint newquota) public {

require(msg.sender == organizer);

quota = newquota;

}

 

function refundTicket(address recipient, uint amount,uint ticketNumber) payable public{

require(msg.sender == organizer);

if (registrantsPaid[recipient] >= amount) {

//address myAddress = this;

if (organizer.balance >= amount) {

recipient.transfer(amount);

Refund(recipient, amount);

registrantsPaid[recipient] -= amount;

numRegistrants-=ticketNumber;

}

}

return;

}

 

 

function destroy () public{

require(msg.sender == organizer);// without this funds could be locked in the contract forever!

selfdestruct(organizer);

 

}

}

*在Node1命令行中审视一下自己编辑的合约:solc –gas Conference.sol

*网上说以太坊在标准库方面只实现了非常非常少的一部分,比如SHA3.SHA3操作的基本开销是30gas,之后每个32字节的数据hash需要3gas。内置的StringEqual操作需要5 gas的基本开销,随后比较每个字节需要1 gas

 

用IDE编译成Conference,js后,回到geth,可以导入合约。!注意,这个过程矿机不能停。!

 

> loadScript(‘./Conference.js’)

null [object Object]

true

> null [object Object]

Contract mined! address: 0xcbf1b22ad7eda3482f7f00948539ea5684a6882b transactionHash: 0xb7c3a8c1282baef3c7b7063b1a96b10e28ff26a2c1fe9fd5a3c81ccbafcbea7d

 

我们可以看到合约有一个address,意味着它能收发以太值,以及一个transactionHash,用它来找到区块链中的位置。直接输入ss(我们初始化的实例名字),发现合约的abi信息以及公共的可调用的函数也列出了。abi是Application Binary Interface的缩写,字面意思 应用二进制接口,可以通俗的理解为合约的接口说明。当合约被编译后,那么它的abi也就确定

现在让我们调用下:

ss.changeQuota.sendTransaction(100)

Error: invalid address

at web3.js:3930:15

at web3.js:3756:20

at web3.js:5025:28

at map (<native code>)

at web3.js:5024:12

at web3.js:5050:18

at web3.js:5075:23

at web3.js:4137:16

at <anonymous>:1:1

我去,没成功。再试试这个:

> ss.quota()

100

> ss.changeQuota.sendTransaction(200,{from:eth.coinbase})

“0x44acef0216b4da50e32a25bdaaf074ddd349f23280f181bf0d284c32769830d2”

> ss.quota()

100

> ss.quota()

200

由于web3.js封装了合约调用的方法。我们可以使用可以使用web3.eth.contract的里的sendTransaction来修改区块链数据。在这里有个坑,有可能会出现Error: invalid address,原因是没有传from,交易发起者的地址。在使用web3.js的API都需留意,出现这种找不到地址的,都看看from字段吧。

 

接下来看看gas消耗的情况:

Node1:

> ss.organizer()

“0xf4182f0dc92313f8e106fc033641c3351703911f”

> eth.getBalance(“0xf4182f0dc92313f8e106fc033641c3351703911f”)

2.0000037903157114008e+28

为了保证合约内容讲解的完成性,这块我们要穿越到第二天Node2节点已经搭建完成了!

Node2:

var bb=eth.contract.(abi).at(address);//这是在新节点初始化合约的方法

> personal.unlockAccount(eth.coinbase)

Unlock account 0xf2ad598bb92b28989d1e8bf686f0e07a8a036a5a

Passphrase:

true

> eth.getBalance(eth.coinbase)

9.574379388346e+21

> bb.buyTicket.sendTransaction(2,{from:eth.coinbase,value:web3.toWei(2)})

“0x2f5bf547eadbff0c96db240aa896990142bd23f769be87f2e459261caf8d633c”

> eth.getBalance(eth.coinbase)

9.572378091716e+21

> eth.getTransaction(“0x2f5bf547eadbff0c96db240aa896990142bd23f769be87f2e459261caf8d633c”)

{

blockHash: “0xb207210430239571b5d999c4c000f065d66e660b64045e6218e179a817f8c006”,

blockNumber: 8422,

from: “0xf2ad598bb92b28989d1e8bf686f0e07a8a036a5a”,

gas: 90000,

gasPrice: 18000000000,

hash: “0x2f5bf547eadbff0c96db240aa896990142bd23f769be87f2e459261caf8d633c”,

input: “0x67dd74ca0000000000000000000000000000000000000000000000000000000000000002”,

nonce: 42,

r: “0xef743cab7bdf70706052877ab675a289094a56e1f0241f618b7eb7ad73b273a7”,

s: “0x5cb18b44f1e3276c8f695ad126a578ebe1badd2f532b7d4139592eb2bd3e05f7”,

to: “0xfbcd7a73ff412512117300f59248f4281579c80f”,

transactionIndex: 0,

v: “0x3c”,

value: 2000000000000000000

}

>  9.574379388346e+21-9.572378091716e+21//少了这么多钱

2001296630000648200

> 2001296630000648200-2000000000000000000//减掉票钱

1296630000648192

> 1296630000648192/18000000000

72035.00003601066//大概花了这么多gas

 

创建新Node

登录246服务器,修改genesis.json!!!!!错误!!!!这文件一个字都不能改。

geth –datadir “/home/appadmin/.ethereum” init eth/genesis.json

./start.sh删除unlock和password, 修改rpcaddr为246

 

 

在Node1的 boot node 上获取 enode 信息

> admin.nodeInfo.enode

“enode://2794bb6a9439d80c55c394328b396105adff8f5a2c9686fd56945024ebadb847ac2bbca2266742138ddfb94a03ceccbcd98b1caffc4820d1ead5c369234aad8b@[::]:30303”

替换:

“enode://2794bb6a9439d80c55c394328b396105adff8f5a2c9686fd56945024ebadb847ac2bbca2266742138ddfb94a03ceccbcd98b1caffc4820d1ead5c369234aad8b@10.120.113.245:30303”

将 boot node 的 enode 信息写入 node2

>admin.addPeer(“enode://2794bb6a9439d80c55c394328b396105adff8f5a2c9686fd56945024ebadb847ac2bbca2266742138ddfb94a03ceccbcd98b1caffc4820d1ead5c369234aad8b@10.120.113.245:30303”)

true

> admin.peers

[]

> admin.peers

[{

caps: [“eth/62”, “eth/63”],

id: “edcc39c963e128555c192be58ddd387a674aba2123ec7daef9144b6ff109ac5712bcfea3904a63031fcdbbfae30c26bb6148af0c559944b34f00d0cd2889688c”,

name: “Geth/v1.8.2-stable-b8b9f7f4/linux-amd64/go1.9.4”,

network: {

inbound: true,

localAddress: “10.120.113.245:30303”,

remoteAddress: “10.120.113.246:48204”,

static: false,

trusted: false

},

protocols: {

eth: {
difficulty: 7035219,

head: “0xf8b772c1b23cd8bea305aa52f13cd68a1697339e86f9badd5d064502c3c84e65”,

version: 63

}

}

}]

也可以在start.sh中直接指定Node1的信息

#!/bin/sh

geth –ipcdisable –rpc –rpcaddr “10.120.113.246”  –port 30303 –rpcport 8101 –rpccorsdomain “*” –networkid 12 –datadir ‘~/.ethereum’ –bootnodes “enode://3d6ff07e12e59a4dbd972e5d8ed33578570203c852f9837b263a04fa91bc9c795b46cbd3ee801a67aa741e317fcd734409bf1e81c8a4e81e6e27f420fd25ba0a@10.120.113.245:30303” console 2>>log

这样新节点就添加完成了,他们之间的通信就是p2p的方式了。

Categories: 感悟 Tags:

基于以太坊私有链搭建一个分布式应用【1】0+

4,521 views / 2018.03.15 / 9:09 下午

这几天不分白昼的看各种英文文档和stackoverflow,终于把区块链这套基本的框架和流程搞通了,感觉十分不容易,故做个分享。不过,如果你时间充裕,请直接阅读英文官方文档:http://www.ethdocs.org/en/latest/,不要看我们这些囫囵吞枣的内容。如果阅读有困难,可以从本文先找找感觉。

名词解释

Ethereum–以太坊,是一个开源的有智能合约功能的公共区块链平台

公有链、私有链、联盟链–公有链不解释;私有链是指其写入权限由某个组织和机构控制的区块链,参与节点的资格会被严格限制;联盟链是指有若干个机构共同参与管理的区块链,每个机构都运行着一个或多个节点,其中的数据只允许系统内不同的机构进行读写和发送交易,并且共同来记录交易数据。

Geth–对应软件包ethereum,又名Go Ethereum,是以太坊协议的三种实现之一,由Go语言开发,完全开源的项目。Geth 可以被安装在很多操作系统上,包括Windows、Linux、Mac的OSX、Android或者IOS系统

Solidity–对应软件包solc,是一种语法类似JavaScript的高级语言。它被设计成以编译的方式生成以太坊虚拟机代码。

gas— cost = gasPrice * gasUsed, gaslimit是由发起者设置的,gasPrice是双方博弈的。

truffle:合约编译、测试、发布框架工具

以太坊中的数据单位

* ether

* finney

* szabo

* wei

* 1 ether = 1 * 10^18 wei;

* 1 ether = 1 * 10^6 szabo;

* 1 ehter = 1* 10^3 finney;

程序在处理交易的时候用的单位都是wei

 

系统准备

两台同网段的linux云虚机,内存必须>=2G

系统建议使用最新的ubuntu版本,可以省却很多编译的麻烦。如果是centos>7.0。

本问采用两台ubuntu系统:

10.120.113.245—简称node1服务器

10.120.113.246—简称node2服务器

 

node1服务器搭建

 

安装geth:

sudo apt-get install software-properties-common

sudo add-apt-repository -y ppa:ethereum/ethereum

sudo add-apt-repository -y ppa:ethereum/ethereum-dev

sudo apt-get update

sudo apt-get install ethereum

安装solc编译器

sudo apt-get install solc

 

先创建3个账号,作为创世大神用的。以下代码运行三次。

appadmin@ubuntu:~$ geth account new

INFO [03-06|17:39:52] Maximum peer count                       ETH=25 LES=0 total=25

Your new account is locked with a password. Please give a password. Do not forget this password.

Passphrase:

Repeat passphrase:

Address: {e2b44335459830c43aaede94a6c748b40f5bfb26}

 

开始创造世界,先编辑个genesis.json文件:

{

“nonce”: “0x0000000000000042”, //Number once

“difficulty”: “0x1”,//挖矿的难度

“alloc”: {//给三个创世大神初始化钱

“f4182f0dc92313f8e106fc033641c3351703911f”: {

“balance”: “20000009800000000000000000000”

},

“899a969874bec249e4ef439c75adb0c358913b95”: {

“balance”: “20000009800000000000000000000”

},

“6797c39109ec4676d3b5dbb4dc76f1143a0f633a”: {

“balance”: “20000009800000000000000000000”

}

},

“config”: {

“chainId”: 12,//1-8不能用,详情https://ethereum.stackexchange.com/questions/17051/how-to-select-a-network-id-or-is-there-a-list-of-network-ids

“homesteadBlock”: 0,

“eip155Block”: 0,

“eip158Block”: 0

},

“mixhash”: “0x0000000000000000000000000000000000000000000000000000000000000000”, “coinbase”: “0x0000000000000000000000000000000000000000”,

 

“timestamp”: “0x00”,

 

“parentHash”: “0x0000000000000000000000000000000000000000000000000000000000000000”,

 

“extraData”: “0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa”,//传啥都行,但必须符合这格式

 

“gasLimit”: “0xb2d05e00”

}

好,把上面这个json文件放到eth目录中,执行如下代码:

geth –datadir “/home/appadmin/.ethereum” init eth/genesis.json

 

创建成功后,编写个启动脚本start.sh:

#!/bin/sh

geth –ipcdisable –rpc –rpcaddr “10.120.113.245” –port 30303 –rpcport 8101 –rpccorsdomain “*” –unlock ‘0,1,2’ –password ~/eth/password –networkid 12 –datadir ‘~/.ethereum’  console 2>>log

rpc是对外通信用的, ipc是内部通信用的,如果ipcdisable会无法在新的会话中attach到这个节点中,保证安全性(相反,可以geth attach新开一个控制台)

命令中会用password密码文件解锁以上三个账号,下文会解释为何要解锁。

保存,chmod +x start.sh 让其可执行

然后运行./start.sh其中控制台,稍后片刻就进入了。

 

查看节点下的创世大神们都有谁:

> eth.accounts

[“0xe2b44335459830c43aaede94a6c748b40f5bfb26”, “0x83817fa106fee9cfe149c9548e3656bffda90987”, “0x58a87b6080a226750f1e9e6d0f999ddfbc1bf914”]

 

开始挖矿钱,先看看矿机在谁的控制下:

eth.coinbase

可以通过这个命令设置所有者:

miner.setEtherbase(eth.accounts[2])

 

开始挖矿

> miner.start()

null

 

查看账户有多少钱了,上面说过,单位都是wei

> eth.getBalance('0xe2b44335459830c43aaede94a6c748b40f5bfb26')

2.0000019635e+28

> eth.getBalance('0x83817fa106fee9cfe149c9548e3656bffda90987')

2.00000098e+28

> eth.getBalance('0xbcf5b841303bc08026ce2d3b8f83498ffe42c12f')

0

 

可以使用eth.blockNumber查看一下区块高度是否增加。

> eth.blockNumber

1982

> eth.blockNumber

1985

> miner.stop()

true

> eth.blockNumber

1991

> eth.blockNumber

1991

> eth.blockNumber

1991

 

再创建个新账号:

> personal.newAccount()

Passphrase:

Repeat passphrase:

“0xdc23fc95dc3d452a210652be55195f5f743167ed”

> eth.accounts

[“0xe2b44335459830c43aaede94a6c748b40f5bfb26”, “0x83817fa106fee9cfe149c9548e3656bffda90987”, “0x58a87b6080a226750f1e9e6d0f999ddfbc1bf914”, “0xdc23fc95dc3d452a210652be55195f5f743167ed”]

 

> eth.getBalance(‘0xdc23fc95dc3d452a210652be55195f5f743167ed’)

0

 

执行转账命令,看看好不好使,结果发现报错:

> eth.sendTransaction({from: eth.accounts[3], to: eth.accounts[0], value: 120000000000000000000})

Error: authentication needed: password or unlock

at web3.js:3143:20

at web3.js:6347:15

at web3.js:5081:36

at <anonymous>:1:1

 

这个是以太坊的一个保护机制,每隔一段时间账户就会自动锁定,这个时候任何以太币在账户之间的转换都会被拒绝,除非把该账户解锁.

这个时候我们就需要执行 personal.unlockAccount(eth.accounts[3]) 并输入密码来解锁eth.accounts[3]才可。

>  personal.unlockAccount(eth.accounts[3])

Unlock account 0xdc23fc95dc3d452a210652be55195f5f743167ed

Passphrase:

true

> eth.sendTransaction({from: eth.accounts[3], to: eth.accounts[0], value: 120000000000000000000})

Error: insufficient funds for gas * price + value

at web3.js:3143:20

at web3.js:6347:15

at web3.js:5081:36

at <anonymous>:1:1

>  eth.gasPrice

18000000000

> eth.estimateGas({from: eth.accounts[2], to: eth.accounts[0], value: 120000000000000000000})

21000

由 于cost = gas * gasPrice , ( 账户3减少的资产 – 账户0增加的资产)/ gasPrice = 消耗的gas

 

> personal.unlockAccount(eth.accounts[2])

Unlock account 0xdc23fc95dc3d452a210652be55195f5f743167ed

Passphrase:

true

> eth.sendTransaction({from: eth.accounts[2], to: eth.accounts[0], value: 110000000000000000000})

“0xc27f031a26c80db62e959a00fe17325bed32820d6497076eedfd50fd51e5330a”

 

这时候可以看到矿池里面有未打包的交易,需要等矿工打包完成。

> txpool.status

{

pending: 1,

queued: 0

}

通过getTransation查看交易详情。

> eth.getTransaction(‘0xc27f031a26c80db62e959a00fe17325bed32820d6497076eedfd50fd51e5330a’)

{

blockHash: “0x0000000000000000000000000000000000000000000000000000000000000000”,

blockNumber: null,

from: “0x58a87b6080a226750f1e9e6d0f999ddfbc1bf914”,

gas: 90000,

gasPrice: 18000000000,

hash: “0xc27f031a26c80db62e959a00fe17325bed32820d6497076eedfd50fd51e5330a”,

input: “0x”,

nonce: 0,

r: “0x37114e0086c08a33cca996ba3a0ac3b263bf974e539f7a4c2136a2dca0bfe67a”,

s: “0x2b88f2a5abc23e8a21759589e4a7565fbfe61768e5b00b4e0b0056d4824087ca”,

to: “0xe2b44335459830c43aaede94a6c748b40f5bfb26”,

transactionIndex: 0,

v: “0x3b”,

value: 110000000000000000000

}

至此,node1节点搭建完成。下一章我们来看怎么编写和执行一个合约。

Categories: 感悟 Tags:

PHP7中安装mysql的扩展以支持mysql_connect0+

8,862 views / 2018.03.02 / 5:05 下午

错误现象:PHP Fatal error: Uncaught Error: Call to a member function mysql_connect()…
解决步骤:
1. http://git.php.net/?p=pecl/database/mysql.git;a=summary 下载最新版本,解压
2. apt install php7.0-dev 不安装没有phpize
3. phpize
4. ./configure –with-php-config=/usr/bin/php-config –with-mysql=mysqlnd
5. make && make install
6. echo ‘extension=mysql.so’>/etc/php/7.0/mods-available/mysql.ini
7. phpenmod mysql
8. 重启apache2

Categories: 感悟 Tags:

php-fpm卡死,经查是pcscd服务占用了太多连接数2+

11,540 views / 2016.10.05 / 3:03 下午

业务量太大的时候,lnmp下的php-fpm就卡死了。查了半天,发现有个pcscd.comm占用了好几千个连接数,极其壮观:
8279987326chatroom_1475651969324_62
查linux官方文档,解释这个服务:
pcscd is the daemon program for pcsc-lite and the MuscleCard framework. It is a resource manager that coordinates communications with smart card readers and smart cards and cryptographic tokens that are connected to the system.pcscd is normally started at boot time from /etc/init.d/pcscd. It allows applications to access smart cards and readers without knowing details of the card or reader.
原来是智能卡的支持服务,果断关掉:
[admin@APP5 ~]$ sudo service pcscd stop
Stopping PC/SC smart card daemon (pcscd): [ OK ]
查看连接数,瞬间降下来了。
然后chkconfig 把pcscd服务自启动给禁用掉:
chkconfig pcscd off
搞定。
至于为什么启动了这么多连接数,具体原因未明,估计是linux虚拟机系统没配置好。

Categories: 感悟 Tags: ,