diff --git a/protocol/invocation/rpcinvocation.go b/protocol/invocation/rpcinvocation.go
index 10c0efe9cdb6194061fcecfb24c4bf5130dc7fec..35474e54e6bfa9f46e159c75d905936ff2f8ca5d 100644
--- a/protocol/invocation/rpcinvocation.go
+++ b/protocol/invocation/rpcinvocation.go
@@ -52,6 +52,7 @@ func NewRPCInvocation(methodName string, arguments []interface{}, attachments ma
 		methodName:  methodName,
 		arguments:   arguments,
 		attachments: attachments,
+		attributes:  make(map[string]interface{}, 8),
 	}
 }
 
@@ -142,6 +143,16 @@ func (r *RPCInvocation) SetAttachments(key string, value string) {
 	r.attachments[key] = value
 }
 
+// SetAttribute. If Attributes is nil, it will be inited.
+func (r *RPCInvocation) SetAttribute(key string, value interface{}) {
+	r.lock.Lock()
+	defer r.lock.Unlock()
+	if r.attributes == nil {
+		r.attributes = make(map[string]interface{})
+	}
+	r.attributes[key] = value
+}
+
 // Invoker ...
 func (r *RPCInvocation) Invoker() protocol.Invoker {
 	return r.invoker
@@ -217,6 +228,12 @@ func WithAttachments(attachments map[string]string) option {
 	}
 }
 
+func WithAttributes(attributes map[string]interface{}) option {
+	return func(invo *RPCInvocation) {
+		invo.attributes = attributes
+	}
+}
+
 // WithInvoker ...
 func WithInvoker(invoker protocol.Invoker) option {
 	return func(invo *RPCInvocation) {