本文的目的是介绍goLDAP连接池实现【LDAPResultCode200\"NetworkError\":ldap:connectionisinstartlsphase】的详细情况,我们将通过专业的
本文的目的是介绍go LDAP 连接池实现 【LDAP Result Code 200 \"Network Error\": ldap: connection is in startls phase】的详细情况,我们将通过专业的研究、有关数据的分析等多种方式,同时也不会遗漏关于Android Studio 3.1.4 buildApk遇到问题 Connection reset、asp.net-core – 来自带有Entity Framework Core的Data Tier中的appsettings.json的ConnectionString、c# – Net Core Connection String Dapper visual studio 2017、Client network socket disconnected before secure TLS connection was established的知识。
本文目录一览:- go LDAP 连接池实现 【LDAP Result Code 200 \"Network Error\": ldap: connection is in startls phase】
- Android Studio 3.1.4 buildApk遇到问题 Connection reset
- asp.net-core – 来自带有Entity Framework Core的Data Tier中的appsettings.json的ConnectionString
- c# – Net Core Connection String Dapper visual studio 2017
- Client network socket disconnected before secure TLS connection was established
go LDAP 连接池实现 【LDAP Result Code 200 \"Network Error\": ldap: connection is in startls phase】
LDAP 连接池
简介
场景:写了个定时任务,每天下午 5 点根据 HR 数据对全量 LDAP 用户作更新,因为 LDAP 协议是一种可以快速读但修改操作慢的协议,因此定时任务执行时间会很长。于是决定并发地对全量用户进行更新,假设并发数是 20,那么一次性会开始创建 20 个 LDAP 连接,因为 LDAP 连接速度较慢,会报错 LDAP Result Code 200 \"Network Error\": ldap: connection is in startls phase
。
通过思考和调研,决定仿照 MySQL、Redis 连接池那样在主进程启动后先初始化 LDAP 连接池。找到并改写 5 年前一个国外的老仓库,并测试通过,完美地解决了问题。现将源码和使用方式给出,后面也会作优化~
源码: randolphcyg/ldappool
使用方式
// 拉下包
go get "github.com/randolphcyg/ldappool"
// 导入
import ldappool "github.com/randolphcyg/ldappool"
示例
在自己的项目中写一个 Init 函数,主进程中解析出来 ldap 服务器连接信息后初始化 ldap 连接池,得到一个全局的连接池对象 LdapPool
,用到的地方用 LdapPool.Get()
获取连接即可。后续开发若有并发修改 ldap 信息的需求,即可快速从连接池取连接,作并发操作。
package main
import (
"crypto/tls"
"fmt"
"time"
"unicode/utf16"
"github.com/randolphcyg/ldappool"
"github.com/go-ldap/ldap/v3"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
)
func main() {
c := &ldapCfg{
ConnUrl: "ldap://192.168.xx.xx:389",
SslEncryption: true,
Timeout: 5 * time.Second,
BaseDn: "DC=xxx,DC=com",
AdminAccount: "CN=Admin,CN=Users,DC=xxx,DC=com",
Password: "xxx",
}
// 初始化配置ldap连接池
Init(c)
// 待查询用户
ldapUser := &LdapAttributes{
Num: "工号",
DisplayName: "姓名",
}
entry, err := FetchUser(ldapUser)
if err != nil {
logrus.Error("fail to fetch ldap user", err)
}
fmt.Println(entry.DN)
}
// LdapConnCfg LDAP服务器连接配置
type ldapCfg struct {
gorm.Model
// 连接地址
ConnUrl string `json:"conn_url" gorm:"type:varchar(255);unique_index;not null;comment:连接地址 逻辑外键"`
// SSL加密方式
SslEncryption bool `json:"ssl_encryption" gorm:"type:tinyint;length:1;comment:SSL加密方式"`
// 超时设置
Timeout time.Duration `json:"timeout" gorm:"type:int;comment:超时设置"`
// 根目录
BaseDn string `json:"base_dn" gorm:"type:varchar(255);not null;comment:根目录"`
// 用户名
AdminAccount string `json:"admin_account" gorm:"type:varchar(255);not null;comment:用户名"`
// 密码
Password string `json:"password" gorm:"type:varchar(255);not null;comment:密码"`
}
var LdapCfg *ldapCfg
var LdapPool ldappool.Pool
// Init 初始化连接池
func Init(c *ldapCfg) (err error) {
LdapCfg = &ldapCfg{
ConnUrl: c.ConnUrl,
SslEncryption: c.SslEncryption,
Timeout: c.Timeout,
BaseDn: c.BaseDn,
AdminAccount: c.AdminAccount,
Password: c.Password,
}
// 初始化ldap连接池 TODO 待确认参数
n := utf16.Encode([]rune("3"))
LdapPool, err = ldappool.NewChannelPool(50, 1000, "test",
func(s string) (ldap.Client, error) {
conn, err := ldap.DialURL(LdapCfg.ConnUrl)
if err != nil {
logrus.Error("Fail to dial ldap url, err: ", err)
}
// 重新连接TLS
if err = conn.StartTLS(&tls.Config{InsecureSkipVerify: true}); err != nil {
logrus.Error("Fail to start tls, err: ", err)
}
// 与只读用户绑定
if err = conn.Bind(LdapCfg.AdminAccount, LdapCfg.Password); err != nil {
logrus.Error("admin user auth failed, err: ", err)
}
return conn, nil
}, n)
if err != nil {
logrus.Error(err.Error())
}
return
}
type LdapAttributes struct {
// ldap字段
Num string `json:"employeeNumber" gorm:"type:varchar(100);unique_index"` // 工号
Sam string `json:"sAMAccountName" gorm:"type:varchar(128);unique_index"` // SAM账号
Dn string `json:"distinguishedName" gorm:"type:varchar(100);unique_index"` // dn
AccountCtl string `json:"UserAccountControl" gorm:"type:varchar(100)"` // 用户账户控制
Expire int64 `json:"accountExpires" gorm:"type:int(30)"` // 账户过期时间
PwdLastSet string `json:"pwdLastSet" gorm:"type:varchar(100)"` // 用户下次登录必须修改密码
WhenCreated string `json:"whenCreated" gorm:"type:varchar(100)"` // 创建时间
WhenChanged string `json:"whenChanged" gorm:"type:varchar(100)"` // 修改时间
DisplayName string `json:"displayName" gorm:"type:varchar(32)"` // 真实姓名
Sn string `json:"sn" gorm:"type:varchar(100)"` // 姓
Name string `json:"name" gorm:"type:varchar(100)"` // 姓名
GivenName string `json:"givenName" gorm:"type:varchar(100)"` // 名
Email string `json:"mail" gorm:"type:varchar(128);unique_index"` // 邮箱
Phone string `json:"mobile" gorm:"type:varchar(32);unique_index"` // 移动电话
Company string `json:"company" gorm:"type:varchar(128)"` // 公司
Depart string `json:"department" gorm:"type:varchar(128)"` // 部门
Title string `json:"title" gorm:"type:varchar(100)"` // 职务
}
var attrs = []string{
"employeeNumber", // 工号
"sAMAccountName", // SAM账号
"distinguishedName", // dn
"UserAccountControl", // 用户账户控制
"accountExpires", // 账户过期时间
"pwdLastSet", // 用户下次登录必须修改密码
"whenCreated", // 创建时间
"whenChanged", // 修改时间
"displayName", // 显示名
"sn", // 姓
"name",
"givenName", // 名
"mail", // 邮箱
"mobile", // 手机号
"company", // 公司
"department", // 部门
"title", // 职务
"cn", // common name
}
/* 根据cn查询用户 注意: cn查询不到则会返回管理员用户
* 这里的查询条件必须保证每个用户必须有
* 根据cn查询用户 [sam登录名字段也出现了不同的版本 邮箱\手机号都可能更换掉 真实姓名存在重复可能]
*/
func FetchUser(user *LdapAttributes) (result *ldap.Entry, err error) {
// 获取连接
LdapConn, err := LdapPool.Get()
if err != nil {
logrus.Error("Fail to get ldap connection, err: ", err)
return
}
defer LdapConn.Close()
ldapFilterCn := "(cn=" + user.DisplayName + user.Num + ")"
searchFilter := "(objectClass=organizationalPerson)"
if user.DisplayName != "" && user.Num != "" {
searchFilter += ldapFilterCn
}
searchFilter = "(&" + searchFilter + ")"
searchRequest := ldap.NewSearchRequest(
LdapCfg.BaseDn,
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
searchFilter,
attrs,
nil,
)
// 这里LdapConn 为nil
sr, err := LdapConn.Search(searchRequest)
if err != nil {
logrus.Error("Fail to fetch user, err: ", err)
return
}
if len(sr.Entries) > 0 && len(sr.Entries[0].Attributes) > 0 {
result = sr.Entries[0]
}
return
}
问题
15 分钟后创建的 50 个 ldap 连接会被关闭,如何解决这个问题呢?
将 NewChannelPool
的 aliveChecks
改为 true
即可。这个是允许存活校验。
failed to send closeNotify alert (but connection was closed anyway): write tcp x.x.x.x:13739->x.x.x.x:389: wsasend: An existing connection was forcibly closed by the remote host.
Android Studio 3.1.4 buildApk遇到问题 Connection reset
打开设置,找到Android Studio选项卡,把下图选项打上勾就ok
asp.net-core – 来自带有Entity Framework Core的Data Tier中的appsettings.json的ConnectionString
我看到的所有示例都在startup.cs的UI层中配置了dbcontext.这就是我想要避免的.
问题Here得到了主题.
解决方法
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; namespace your.service.layer { public static class MyServiceCollectionExtensions { public static IServiceCollection AddMyServiceDependencies(this IServiceCollection services,string connectionString) { services.AddEntityFrameworksqlServer() .AddDbContext<YourDbContext>((serviceProvider,options) => options.UsesqlServer(connectionString) .UseInternalServiceProvider(serviceProvider) ); return services; } } }
启动:
using your.service.layer; public void ConfigureServices(IServiceCollection services) { var connectionString = Configuration.GetConnectionString("EntityFrameworkConnectionString"); services.AddMyServiceDependencies(connectionString); }
现在,您的网络应用仅需要对您的业务/服务层的引用,并且它不直接依赖于EntityFramework.
c# – Net Core Connection String Dapper visual studio 2017
System.NullReferenceException:’对象引用未设置为对象的实例.’
我尝试将以下内容添加到appsettings.json:
"ConnectionStrings": { "Analysis": "Server=DESKTOP-MYSERVER;Database=MYDATABASE;User Id=sa; Password=Password123;Provider=System.Data.sqlClient;Trusted_Connection=True;MultipleActiveResultSets=true;Pooling=false;" }
我也试过像以前那样使用web.config .Net Core:
<connectionStrings> <add name="Analysis" providerName="System.Data.sqlClient" connectionString="Server=DESKTOP-MYSERVER;Database=MYDATABASE;User Id=sm;Password=Password123;"/>
然后在c#我有:
public List<DapperTest> ReadAll() { var data = new List<DapperTest>(); using (IDbConnection db = new sqlConnection(ConfigurationManager.ConnectionStrings["Analysis"].ConnectionString)) { data = db.Query<DapperTest>("select * from testTable").ToList(); } return data; }
两种方式都给我例外:
System.NullReferenceException:’对象引用未设置为对象的实例.’
我使用了以下资源:
.Net CORE Dapper Connection String?
https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro
Get connection string from App.config
但我错过了一些东西.我只设置了一次连接字符串,它不在.Net Core中,因此对其他人来说显而易见.
解决方法
public class ConnectionConfig { public string Analysis {get;set;} }
在Startup.cs中的ConfigureServices方法中添加此行
services.Configure<ConnectionConfig>(Configuration.GetSection("ConnectionStrings"));
数据服务类
class YourClass{ private string _connectionString; YourClass(string connectionString){ _connectionString = connectionString; } //Your implementation public List<DapperTest> ReadAll() { var data = new List<DapperTest>(); using (IDbConnection db = new sqlConnection(_connectionString) { data = db.Query<DapperTest>("select * from testTable").ToList(); } return data; } }
注入IOptions< ConnectionConfig>在你的控制器构造函数中.
class YourController : Controller{ YourClass _testing; YourController(IOptions<ConnectionConfig> connectionConfig){ var connection = connectionConfig.Value; string connectionString = connection.Analysis; _testing = new YourClass(connectionString ); } public IActionResult Index() { var testingData = _testing.ReadAll(); return View(); } }
Client network socket disconnected before secure TLS connection was established
标题:Client network socket disconnected before secure TLS connection was established
我在使用 SAP Spartacus 连接 Commerce Cloud 后台 OCC API 时,遇到如下错误消息:
Error: Client network socket disconnected before secure TLS connection was established
at connResetException (internal/errors.js:610:14)
at TLSSocket.onConnectEnd (_tls_wrap.js:1546:19)
at Object.onceWrapper (events.js:421:28)
at ZoneDelegate.invokeTask (c:\Code\SPA\strange\mystore\dist\mystore\server\main.js:140414:35)
at Object.onInvokeTask (c:\Code\SPA\strange\mystore\dist\mystore\server\main.js:174114:33)
at ZoneDelegate.invokeTask (c:\Code\SPA\strange\mystore\dist\mystore\server\main.js:140413:40)
at Zone.runTask (c:\Code\SPA\strange\mystore\dist\mystore\server\main.js:140181:51)
at ZoneTask.invokeTask (c:\Code\SPA\strange\mystore\dist\mystore\server\main.js:140496:38)
at TLSSocket.ZoneTask.invoke (c:\Code\SPA\strange\mystore\dist\mystore\server\main.js:140485:52)
at TLSSocket.emit (events.js:327:22)
调试截图:
解决方案
将所有的 OCC 调用经过一个本地 reverse-proxy 进行路由 (基于 npm http-proxy-cli)。
(1) set “CX_BASE_URL”: “http://localhost:4500” in .env-cmdrc file (:4500, 端口可以任意指定)
(2) rebuild app and ssr, and serve ssr
Proxy calls to our OCC dev server (https://40……) through http://localhost:4500 , and ignore TLS issues (–no-verify), and optionally make it verbose (-v)
使用下面的命名行安装 http-proxy-cli
$ npm install -g http-proxy-cli
run
$ http-proxy -p 4500 -P --no-verify -v https://40.x.x.x:9002
更多 Jerry 的原创文章,尽在:“汪子熙”:
本文同步分享在 博客 “汪子熙”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与 “OSC 源创计划”,欢迎正在阅读的你也加入,一起分享。
我们今天的关于go LDAP 连接池实现 【LDAP Result Code 200 \"Network Error\": ldap: connection is in startls phase】的分享就到这里,谢谢您的阅读,如果想了解更多关于Android Studio 3.1.4 buildApk遇到问题 Connection reset、asp.net-core – 来自带有Entity Framework Core的Data Tier中的appsettings.json的ConnectionString、c# – Net Core Connection String Dapper visual studio 2017、Client network socket disconnected before secure TLS connection was established的相关信息,可以在本站进行搜索。
本文标签: