热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

OpenStackSwift集群与Keystone的整合方法

之前已经介绍了OpenStackSwift集群和Keystone的安装部署,最后来讲一讲Swift集群与Keystone的整合使用吧。本文档描述了Keystone与Swift集群的整合使用方法,即Swift通过Keystone完成用户的身份认证与权限控制,而不是采用自带的TempAuth。本文档假定如

之前已经介绍了OpenStack Swift集群Keystone的安装部署,最后来讲一讲Swift集群与Keystone的整合使用吧。

  本文档描述了Keystone与Swift集群的整合使用方法,即Swift通过Keystone完成用户的身份认证与权限控制,而不是采用自带的TempAuth。本文档假定如下前提条件:

用户已阅读文档《Keystone安装部署流程》和《Swift集群部署流程》,并按照上述文档分别部署了Keystone与Swift集群。

用户已掌握了Keystone与Swift的基本使用方法。

所有PC使用Ubuntu操作系统。

Keystone部署在PC1上,Swift集群部署在PC2和PC3上。

PC2和PC3都运行Swift的所有服务,既是Proxy Server,又是Storage Server,用户可以向任何一台发起存储服务请求。

Keystone为多Proxy Server的Swift集群提供身份认证与权限控制。(单Proxy Server的情况比较简单,相信看完本文档后你就懂了)

PC2和PC3构成memcached集群来提供Token缓存服务。

所有操作均在root用户下进行,并使用root作为Swift的用户和组。

所有机器都运行在局域网中。

使用回环设备和XFS文件系统作为Swift底层存储。

  为了能够让Swift通过Keystone完成用户的身份认证与权限控制,我们需要在完成Keystone与Swift集群部署的基础上,稍作修改。

2.1 准备环境

 

PC 1

PC 2

PC 3

机器类型:

PC物理机

PC物理机

PC物理机

操作系统:

Ubuntu-12.04-desktop

(64位)

Ubuntu-12.04-desktop

(64位)

Ubuntu-12.04-desktop

(64位)

用户类型:

root

root

root

数据库:

sqlite3

sqlite3

sqlite3

IP地址:

192.168.3.67(局域网)

192.168.3.52(局域网)

192.168.3.53(局域网)

Keystone

 

 

Proxy Server

Storage Server

Auth

Keystone

Keystone

Token缓存:

memcached

memcached

2.2 版本说明

Swift版本:1.7.6

python-swiftclient版本:1.2.0

Keystone版本:git上的Master版

  可参照文档《Keystone安装部署流程》和《Swift集群部署流程》。Swift需要调用python-keystoneclient中的组件来访问Keystone,因此需要为其安装python-keystoneclient(可采用安装Keystone依赖项的方式)。因此,请务必确保各处安装的Keystone与python-keystoneclient的版本统一,否则可能出现版本兼容性问题(我就曾遇到Swift中安装的python-keystoneclient和PC1上的Keystone服务的版本不统一,导致的版本兼容性问题,无法通过验证,最后重新下载安装所有的python-keystoneclient与Keystone才予以解决)。

2.3 Keystone的部署

  PC1上已经按照文档《Keystone安装部署流程》部署了Keystone,在整合使用过程中无需进行修改。为完整演示Keystone与Swift集群的整合使用过程,我们需要清空Keystone的记录的数据。先删除存储Keystone数据的DB文件,然后同步数据库schema并启动Keystone服务即可。

# rm -f ~/keystone.db

# keystone-manage db_sync

# keystone-all

2.4 Swift集群的部署

  PC2和PC3上已经按照文档《Swift集群部署流程》部署了Swift集群,为了使其能通过Keystone完成用户的身份认证与权限控制,需要对PC2和PC3作出一定的修改。以下操作同时应用于PC2和PC3。

  1. 停掉Swift的所有服务。

  2. Swift需要调用python-keystoneclient中的组件来访问Keystone,因此需要为其安装python-keystoneclient。为了避免版本兼容性问题,推荐采用安装Keystone依赖项的方式,当然你也可以独立地去下载安装python-keystoneclient。我从git上获取最新的Keystone Service代码,安装Keystone的依赖项,并将Keystone安装到Python的package里。这里只安装依赖项中的tools/pip-requires即可,该依赖项中包含了python-keystoneclient。如果安装了tools/test-requires则会覆盖掉已安装的Swift,你就需要自己重新安装Swift了,这在文档《Keystone安装部署流程》中已详细说明。

# cd ~

# git clone https://github.com/openstack/keystone.git

# cd ~/keystone

# pip install -r tools/pip-requires

# python setup.py install

  3. 修改Swift中的proxy-server配置文件/etc/swift/proxy-server.conf。在其中添加authtokenkeystoneauth组件,并将pipeline中的tempauth改为authtoken与keystoneauth,表示采用Keystone而不是TempAuth来完成用户身份认证和权限控制。authtoken是python-keystoneclient中的组件,用于访问Keystone;keystoneauth是Swift中的组件,用于一些附加的条件设置。

[DEFAULT]

bind_port = 8080

user = root

workers = 8

log_facility = LOG_LOCAL1

[pipeline:main]

pipeline = healthcheck cache authtoken keystoneauth proxy-logging proxy-server

[app:proxy-server]

use = egg:swift#proxy

allow_account_management = true

account_autocreate = true

[filter:tempauth]

use = egg:swift#tempauth

user_admin_admin = admin .admin .reseller_admin

user_test_tester = testing .admin

user_test2_tester2 = testing2 .admin

user_test_tester3 = testing3

reseller_prefix = AUTH

token_life = 86400

[filter:authtoken]

paste.filter_factory = keystoneclient.middleware.auth_token:filter_factory

# 以下各项是根据Keystone配置文件中的参数及其所在PC来设置的。

auth_host = 192.168.3.67

# Keystone提供的认证授权、系统管理服务的IP地址,通常为内网。

auth_port = 35357

# Keystone提供的认证授权、系统管理服务监听的端口,通常为内网。

auth_protocol = http

# 访问Keystone所使用的协议,http或https

service_host = 192.168.3.67

# Keystone提供的认证授权服务的IP地址,通常为公网(外网),也可以是内网

service_port = 5000

# Keystone提供的认证授权服务监听的端口,通常为公网(外网),也可以是内网。

admin_token = ADMIN

# admin_token参数是用来访问Keystone服务的,即Keystone服务的Token。可以使用该Token访问Keystone服务、查看信息、创建其他服务等。

[filter:keystoneauth]

use = egg:swift#keystoneauth

operator_roles = adminRole, swiftoperator

# 允许访问并使用Swift的角色

reseller_prefix = AUTH_

# account的命名前缀,注意此处必须加“_”。

# 例如http://192.168.3.52:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5

[filter:healthcheck]

use = egg:swift#healthcheck

[filter:cache]

use = egg:swift#memcache

memcache_servers = 192.168.3.52:11211,192.168.3.53:11211

[filter:proxy-logging]

use = egg:swift#proxy_logging

  4. 至此,我们已经完成了对Swift的修改。现在可以启动Swift服务了

# startmain

# startall

3.1 创建Tenant、User和Role

  我们将创建名称为adminTenant的Tenant(租户)、名称为admin的User(用户)以及名称为adminRole的Role(角色),并将它们关联起来。最终的结果表现为:一个名叫admin的用户,拥有名为adminRole的角色身份,并且能够使用名为adminTennant的租户。需要说明的是:2.4节中配置文件里的“operator_roles = adminRole, swiftoperator”项表明,角色为adminRole或swiftoperator的用户才能访问Swift,所以此处才选择创建adminRole角色。

  1. 创建Tenant,租户名为adminTenant,描述信息为Admin Tenant。请记住该命令生成的Tenant id,下面添加User时需要用到。

# keystone tenant-create --name adminTenant --description "Admin Tenant" --enabled true

+-------------+----------------------------------+

|   Property  |              Value               |

+-------------+----------------------------------+

| description |           Admin Tenant           |

|   enabled   |               True               |

|      id     | 54d3db64adfc4731b5222cac974f8bc5 |

|     name    |           adminTenant            |

+-------------+----------------------------------+

  2. 创建User,用户名为admin,密码为openstack。请记住该命令生成的User id,下面的关联命令需要用到。

# keystone user-create --tenant_id 54d3db64adfc4731b5222cac974f8bc5 --name admin --pass openstack --enabled true

+----------+----------------------------------+

| Property |              Value               |

+----------+----------------------------------+

|  email   |                                  |

| enabled  |               True               |

|    id    | b14c99dbaad14a78a37aa7361201062f |

|   name   |              admin               |

| tenantId | 54d3db64adfc4731b5222cac974f8bc5 |

+----------+----------------------------------+

  3. 创建Role,角色名为adminRole。请记住该命令生成的Role id,下面的关联命令需要用到。

# keystone role-create --name adminRole

+----------+----------------------------------+

| Property |              Value               |

+----------+----------------------------------+

|    id    | 1bf9a3ac155d4fd4abe5646abcc0de7a |

|   name   |            adminRole             |

+----------+----------------------------------+

  4. 至此,我们已经创建了一个Ttenant,一个Uuser以及一个Rrole,它们的id分别是:

tenant_id:54d3db64adfc4731b5222cac974f8bc5

user_id:b14c99dbaad14a78a37aa7361201062f

role_id:1bf9a3ac155d4fd4abe5646abcc0de7a

  5. 最后,我们要使用上述三个id,并通过下面的命令来将三者关联起来。

# keystone user-role-add --user-id b14c99dbaad14a78a37aa7361201062f --tenant-id 54d3db64adfc4731b5222cac974f8bc5 --role-id 1bf9a3ac155d4fd4abe5646abcc0de7a

  此时,让我们再使用list命令查看一下Tenant、User和Role的信息。

+----------------------------------+-------------+---------+

|                id                |     name    | enabled |

+----------------------------------+-------------+---------+

| 54d3db64adfc4731b5222cac974f8bc5 | adminTenant |   True  |

+----------------------------------+-------------+---------+

+----------------------------------+-------+---------+-------+

|                id                |  name | enabled | email |

+----------------------------------+-------+---------+-------+

| b14c99dbaad14a78a37aa7361201062f | admin |   True  |       |

+----------------------------------+-------+---------+-------+

  注:“_member_”角色是Keystone预设的,似乎会和每个用户关联。这是新版本Keystone中出现的,目的暂时不明。

+----------------------------------+-----------+

|                id                |    name   |

+----------------------------------+-----------+

| 9fe2ff9ee4384b1894a90878d3e92bab |  _member_ |

| 1bf9a3ac155d4fd4abe5646abcc0de7a | adminRole |

+----------------------------------+-----------+

3.2 创建Service和Endpoint

  为了让上面创建的用户能够使用Swift存储服务,我们将创建名称为Swift的Service(服务),然后根据现有Swift集群的情况为租户添加Endpoint(端点,服务入口),然后用户就能够访问Endpoint来使用Swift存储服务了。需要说明的是:服务和租户关联后成为Endpoint,即该租户可使用该服务,不同服务和不同租户的组合会产生不同的Endpoint;同时,用户又会和租户相关联,表明用户可使用该租户;于是,只要用户所属的角色被允许访问Swift,那么该用户就能真正地访问并使用Swift了;

  1. 创建Service,服务名为Swift,服务类型为object-store,描述信息为Swift Object Store Service。请记住该命令生成的Service id,下面添加Endpoint时需要用到。

# keystone service-create --name=Swift --type=object-store --description="Swift Object Store Service"

+-------------+----------------------------------+

|   Property  |              Value               |

+-------------+----------------------------------+

| description |    Swift Object Store Service    |

|      id     | cab139be777545a893d1bd26a03730c9 |

|     name    |              Swift               |

|     type    |           object-store           |

+-------------+----------------------------------+

  2. 由于我们的Swift是集群,并且有两个Proxy Server,如果Swift前端存在某种负载均衡设备,那么该负载均衡设备就是唯一的Endpoint(服务入口),用户通过Keystone的认证后,获得的就是这个负载均衡设备的访问地址;然而,我们没有负载均衡设备,这就意味着Swift存在两个Endpoint(服务入口),分别为PC2和PC3,用户通过Keystone的认证后,应该可以同时获得这两个Endpoint,然后随意选取一个来访问。因此,我们需要为租户添加两个Endpoint,分别对应PC2和PC3。

#keystone endpoint-create --region RegionOne --service_id cab139be777545a893d1bd26a03730c9 --publicurl http://192.168.3.52:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5 --adminurl http://192.168.3.52:8080 --internalurl http://192.168.3.52:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5

+-------------+-------------------------------------------------------------------+

|   Property  |                               Value                               |

+-------------+-------------------------------------------------------------------+

|   adminurl  |                      http://192.168.3.52:8080                     |

|      id     |                  6f12e2e82ca44c789c18bdb9d4bbd0dc                 |

| internalurl | http://192.168.3.52:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5 |

|  publicurl  | http://192.168.3.52:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5 |

|    region   |                             RegionOne                             |

|  service_id |                  cab139be777545a893d1bd26a03730c9                 |

+-------------+-------------------------------------------------------------------+

# keystone endpoint-create --region RegionTwo --service_id cab139be777545a893d1bd26a03730c9 --publicurl http://192.168.3.53:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5 --adminurl http://192.168.3.53:8080 --internalurl http://192.168.3.53:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5

+-------------+-------------------------------------------------------------------+

|   Property  |                               Value                               |

+-------------+-------------------------------------------------------------------+

|   adminurl  |                      http://192.168.3.53:8080                     |

|      id     |                  2722feff369b4c2d99fca9e4414276b4                 |

| internalurl | http://192.168.3.53:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5 |

|  publicurl  | http://192.168.3.53:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5 |

|    region   |                             RegionTwo                             |

|  service_id |                  cab139be777545a893d1bd26a03730c9                 |

+-------------+-------------------------------------------------------------------+

  这里解释一下上面的命令:region表示域,原本同一个服务和同一个租户关联产生的Endpoint是唯一的,为使其能支持多个Endpoint(如上文中的PC2和PC3),便加入了域的概念,即同一个服务和同一个租户可以关联产生多个Endpoint,每个Endpoint用region来标示加以区别,如上面的RegionOneRegionTwopublicurl表示该Endpoint的公网(外网)服务入口(普通服务);adminurl表示该Endpoint的管理员服务入口,一般为内网;internalurl表示该Endpoint的内网服务入口(普通服务);本文档的前提环境为局域网,因此publicurl和internalurl可以设置为相同的;192.168.3.52192.168.3.53分别是PC2和PC3的IP地址;AUTH_54d3db64adfc4731b5222cac974f8bc5是“AUTH_”前缀加租户ID,“AUTH_”前缀在2.4节中已有介绍,而租户ID则表明这些Endpoint是由某个特定的租户和Service关联产生的。

  最后,让我们再使用list命令查看一下Service和Endpoint的信息。

+----------------------------------+-----------+-------------------------------------------------------------------+-------------------------------------------------------------------+--------------------------+----------------------------------+

|                id                |   region  |                             publicurl                             |                            internalurl                            |         adminurl         |            service_id            |

+----------------------------------+-----------+-------------------------------------------------------------------+-------------------------------------------------------------------+--------------------------+----------------------------------+

| 2722feff369b4c2d99fca9e4414276b4 | RegionTwo | http://192.168.3.53:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5 | http://192.168.3.53:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5 | http://192.168.3.53:8080 | cab139be777545a893d1bd26a03730c9 |

| 6f12e2e82ca44c789c18bdb9d4bbd0dc | RegionOne | http://192.168.3.52:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5 | http://192.168.3.52:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5 | http://192.168.3.52:8080 | cab139be777545a893d1bd26a03730c9 |

+----------------------------------+-----------+-------------------------------------------------------------------+-------------------------------------------------------------------+--------------------------+----------------------------------+

3.3 用curl测试

  1. 上面已经完成了Tenant、User、Role、Service和Endpoint的创建,于是我们就可以访问Keystone,来获取Token和Endpoint了。我们使用curl命令来访问Keyston,该命令需要给定四个参数,即tenantName(租户名,也可理解为账户名)、username(用户名)、password(用户密码)以及认证与授权申请的地址(http://192.168.3.67:35357/v2.0/tokens或http://192.168.3.67:5000/v2.0/tokens均可)。此外,返回信息会以json格式展现。返回信息比较全面,包括了token和不同region的Endpoint,如下所示:

# curl -d '{"auth": {"tenantName": "adminTenant", "passwordCredentials":{"username": "admin", "password": "openstack"}}}' -H "Content-type: application/json" http://192.168.3.67:5000/v2.0/tokens | python -mjson.tool

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

Dload  Upload   Total   Spent    Left  Speed

100  1301    0  1192  100   109  19348   1769 --:--:-- --:--:-- --:--:-- 19866

{

    "access": {

        "metadata": {

"is_admin": 0,

"roles": [

"9fe2ff9ee4384b1894a90878d3e92bab",

"1bf9a3ac155d4fd4abe5646abcc0de7a"

]

        },

        "serviceCatalog": [

{

                "endpoints": [

{

"adminURL": "http://192.168.3.52:8080",

"id": "482686e2d58644f99971733c3f53f480",

"internalURL": "http://192.168.3.52:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5",

"publicURL": "http://192.168.3.52:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5",

"region": "RegionOne"

},

                    {

"adminURL": "http://192.168.3.53:8080",

"id": "ec6489bafae448088f09c51ddacebeaf",

"internalURL": "http://192.168.3.53:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5",

                        "publicURL": "http://192.168.3.53:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5",

"region": "RegionTwo"

}

],

"endpoints_links": [],

"name": "Swift",

"type": "object-store"

}

        ],

        "token": {

"expires": "2013-04-09T13:51:07Z",

"id": "c8d5d45c42484c7d81d6d2ddd1c1258b",

"issued_at": "2013-04-08T13:51:07.553241",

"tenant": {

"description": "Admin Tenant",

"enabled": true,

"id": "54d3db64adfc4731b5222cac974f8bc5",

"name": "adminTenant"

}

        },

        "user": {

"id": "b14c99dbaad14a78a37aa7361201062f",

"name": "admin",

"roles": [

{

"name": "_member_"

},

{

"name": "adminRole"

}

],

"roles_links": [],

"username": "admin"

        }

    }

}

  2. 接着就可以用获取到的token和Endpoint访问Swift服务了。先用其中一个Endpoint(PC2)查看该Account的信息。

# curl -v -H 'X-Auth-Token: c8d5d45c42484c7d81d6d2ddd1c1258b' http://192.168.3.52:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5

* About to connect() to 192.168.3.52 port 8080 (#0)

*   Trying 192.168.3.52... connected

* Connected to 192.168.3.52 (192.168.3.52) port 8080 (#0)

> GET /v1/AUTH_54d3db64adfc4731b5222cac974f8bc5 HTTP/1.1

> User-Agent: curl/7.21.6 (x86_64-pc-linux-gnu) libcurl/7.21.6 OpenSSL/1.0.0e zlib/1.2.3.4 libidn/1.22 librtmp/2.3

> Host: 192.168.3.52:8080

> Accept: */*

> X-Auth-Token: c8d5d45c42484c7d81d6d2ddd1c1258b

>

<

* Connection #0 to host 192.168.3.52 left intact

* Closing connection #0

# curl -X HEAD -i -H 'X-Auth-Token: c8d5d45c42484c7d81d6d2ddd1c1258b' http://192.168.3.52:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5

HTTP/1.1 204 No Content

Content-Length: 0

Accept-Ranges: bytes

X-Timestamp: 1365429097.95942

X-Account-Bytes-Used: 0

X-Account-Container-Count: 0

Content-Type: text/plain; charset=utf-8

X-Account-Object-Count: 0

Date: Mon, 08 Apr 2013 13:52:18 GMT

  3. 再尝试另一个Endpoint(PC3)查看该的Account信息。

# curl -v -H 'X-Auth-Token: c8d5d45c42484c7d81d6d2ddd1c1258b' http://192.168.3.53:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5

* About to connect() to 192.168.3.53 port 8080 (#0)

*   Trying 192.168.3.53... connected

* Connected to 192.168.3.53 (192.168.3.53) port 8080 (#0)

> GET /v1/AUTH_54d3db64adfc4731b5222cac974f8bc5 HTTP/1.1

> User-Agent: curl/7.21.6 (x86_64-pc-linux-gnu) libcurl/7.21.6 OpenSSL/1.0.0e zlib/1.2.3.4 libidn/1.22 librtmp/2.3

> Host: 192.168.3.53:8080

> Accept: */*

> X-Auth-Token: c8d5d45c42484c7d81d6d2ddd1c1258b

>

<

* Connection #0 to host 192.168.3.53 left intact

* Closing connection #0

  4. 获取该Account中的Container列表,由于未曾创建Container,所以是空的。

# curl -X GET -H 'X-Auth-Token: c8d5d45c42484c7d81d6d2ddd1c1258b' http://192.168.3.53:8080/v1/AUTH_54d3db64adfc4731b5222cac974f8bc5

3.4 用Swift客户端测试

  1. 接着,我们使用Swift客户端进行测试。先查看该Account的信息,提交的参数是Keystone的访问地址、租户名、用户名、用户密码。

# swift -V 2 -A http://192.168.3.67:5000/v2.0 -U adminTenant:admin -K openstack stat

   Account: AUTH_54d3db64adfc4731b5222cac974f8bc5

Containers: 0

   Objects: 0

     Bytes: 0

Accept-Ranges: bytes

X-Timestamp: 1365429097.95942

Content-Type: text/plain; charset=utf-8

  2. 获取该Account中的Container列表,由于未曾创建Container,所以是空的。

# swift -V 2 -A http://192.168.3.67:5000/v2.0 -U adminTenant:admin -K openstack list

  3. 在该Account中创建几个Container。通过查看PC2和PC3上Storage Server的存储目录,可以看到5个Container中有3个存储在PC2上,2个存储在PC3上。

# swift -V 2 -A http://192.168.3.67:5000/v2.0 -U adminTenant:admin -K openstack post myContainer1

# swift -V 2 -A http://192.168.3.67:5000/v2.0 -U adminTenant:admin -K openstack post myContainer2

# swift -V 2 -A http://192.168.3.67:5000/v2.0 -U adminTenant:admin -K openstack post myContainer3

# swift -V 2 -A http://192.168.3.67:5000/v2.0 -U adminTenant:admin -K openstack post myContainer4

# swift -V 2 -A http://192.168.3.67:5000/v2.0 -U adminTenant:admin -K openstack post myContainer5

  4. 再次获取该Account中的Container列表。

# swift -V 2 -A http://192.168.3.67:5000/v2.0 -U adminTenant:admin -K openstack list

myContainer1

myContainer2

myContainer3

myContainer4

myContainer5

  上述使用实例阐述了如何用Keystone为Swift集群提供身份认证与权限控制。结果表明,Keystone正确地为多Proxy Server的Swift集群提供了身份认证与权限控制。至此,你应该已经完整地了解了Keystone和Swift集群的整合使用。

4.1 官方链接

    http://docs.openstack.org/developer/keystone/middlewarearchitecture.html

keystoneclient auth_token does not work with old versions of keystone

    https://bugs.launchpad.net/python-keystoneclient/+bug/1159911


推荐阅读
  • 解决微信电脑版无法刷朋友圈问题:使用安卓远程投屏方案
    在工作期间想要浏览微信和朋友圈却不太方便?虽然微信电脑版目前不支持直接刷朋友圈,但通过远程投屏技术,可以轻松实现在电脑上操作安卓设备的功能。 ... [详细]
  • 本文详细介绍了如何在 Linux 平台上安装和配置 PostgreSQL 数据库。通过访问官方资源并遵循特定的操作步骤,用户可以在不同发行版(如 Ubuntu 和 Red Hat)上顺利完成 PostgreSQL 的安装。 ... [详细]
  • 选择适合生产环境的Docker存储驱动
    本文旨在探讨如何在生产环境中选择合适的Docker存储驱动,并详细介绍不同Linux发行版下的配置方法。通过参考官方文档和兼容性矩阵,提供实用的操作指南。 ... [详细]
  • 嵌入式开发环境搭建与文件传输指南
    本文详细介绍了如何为嵌入式应用开发搭建必要的软硬件环境,并提供了通过串口和网线两种方式将文件传输到开发板的具体步骤。适合Linux开发初学者参考。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • 构建基于BERT的中文NL2SQL模型:一个简明的基准
    本文探讨了将自然语言转换为SQL语句(NL2SQL)的任务,这是人工智能领域中一项非常实用的研究方向。文章介绍了笔者在公司举办的首届中文NL2SQL挑战赛中的实践,该比赛提供了金融和通用领域的表格数据,并标注了对应的自然语言与SQL语句对,旨在训练准确的NL2SQL模型。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 探讨一个显示数字的故障计算器,它支持两种操作:将当前数字乘以2或减去1。本文将详细介绍如何用最少的操作次数将初始值X转换为目标值Y。 ... [详细]
  • 在Ubuntu 16.04 LTS上配置Qt Creator开发环境
    本文详细介绍了如何在Ubuntu 16.04 LTS系统中安装和配置Qt Creator,涵盖了从下载到安装的全过程,并提供了常见问题的解决方案。 ... [详细]
  • MySQL缓存机制深度解析
    本文详细探讨了MySQL的缓存机制,包括主从复制、读写分离以及缓存同步策略等内容。通过理解这些概念和技术,读者可以更好地优化数据库性能。 ... [详细]
  • 本文详细介绍了如何在Ubuntu系统中下载适用于Intel处理器的64位版本,涵盖了不同Linux发行版对64位架构的不同命名方式,并提供了具体的下载链接和步骤。 ... [详细]
  • 本文介绍如何在Linux Mint系统上搭建Rust开发环境,包括安装IntelliJ IDEA、Rust工具链及必要的插件。通过详细步骤,帮助开发者快速上手。 ... [详细]
  • 云计算的优势与应用场景
    本文详细探讨了云计算为企业和个人带来的多种优势,包括成本节约、安全性提升、灵活性增强等。同时介绍了云计算的五大核心特点,并结合实际案例进行分析。 ... [详细]
author-avatar
手机用户2502872597
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有